File Coverage

blib/lib/WWW/Search/AOL.pm
Criterion Covered Total %
statement 51 82 62.2
branch 10 26 38.4
condition 3 7 42.8
subroutine 10 10 100.0
pod 2 2 100.0
total 76 127 59.8


line stmt bran cond sub pod time code
1             package WWW::Search::AOL;
2              
3 4     4   779332 use warnings;
  4         10  
  4         139  
4 4     4   20 use strict;
  4         8  
  4         81  
5              
6 4     4   93 use 5.008;
  4         17  
7              
8             require WWW::Search;
9              
10 4     4   3726 use WWW::SearchResult;
  4         75747  
  4         113  
11 4     4   1730 use Encode;
  4         22474  
  4         352  
12              
13 4     4   24 use Scalar::Util ();
  4         7  
  4         134  
14              
15             =head1 NAME
16              
17             WWW::Search::AOL - backend for searching search.aol.com
18              
19             =head1 VERSION
20              
21             Version 0.0106
22              
23             =cut
24              
25             our $VERSION = '0.0106';
26              
27 4     4   20 use vars qw(@ISA);
  4         7  
  4         3445  
28              
29             @ISA=(qw(WWW::Search));
30              
31             =head1 SYNOPSIS
32              
33             This module provides a backend of L to search using
34             L.
35              
36             use WWW::Search;
37              
38             my $oSearch = WWW::Search->new("AOL");
39              
40             =head1 FUNCTIONS
41              
42             All of these functions are internal to the module and are of no concern
43             of the user.
44              
45             =head2 native_setup_search()
46              
47             This function sets up the search.
48              
49             =cut
50              
51             sub native_setup_search
52             {
53 2     2 1 2046 my ($self, $native_query, $opts) = @_;
54              
55 2         6 $self->{'_hits_per_page'} = 10;
56              
57 2         16 $self->user_agent('non-robot');
58              
59 2         1875399 $self->{'_next_to_retrieve'} = 1;
60              
61 2   50     31 $self->{'search_base_url'} ||= 'http://search.aol.com';
62 2   50     20 $self->{'search_base_path'} ||= '/aolcom/search';
63              
64 2 50       14 if (!defined($self->{'_options'}))
65             {
66 2         16 $self->{'_options'} = +{
67             'query' => $native_query,
68             'invocationType' => 'topsearchbox.webhome',
69             };
70             }
71 2         6 my $self_options = $self->{'_options'};
72              
73 2 50       11 if (defined($opts))
74             {
75 2         8 foreach my $k (keys %$opts)
76             {
77 2 50       11 if (WWW::Search::generic_option($k))
78             {
79 2 50       28 if (defined($opts->{$k}))
80             {
81 2         8 $self->{$k} = $opts->{$k};
82             }
83             }
84             else
85             {
86 0 0       0 if (defined($opts->{$k}))
87             {
88 0         0 $self_options->{$k} = $opts->{$k};
89             }
90             }
91             }
92             }
93              
94 2         30 $self->{'_next_url'} = $self->{'search_base_url'} . $self->{'search_base_path'} . '?' . $self->hash_to_cgi_string($self_options);
95 2         131 $self->{'_AOL_first_retrieve_call'} = 1;
96             }
97              
98             =head2 parse_tree()
99              
100             This function parses the tree and fetches the results.
101              
102             =cut
103              
104             sub _no_hits
105             {
106 2     2   5 my $self = shift;
107              
108 2         26 $self->approximate_result_count(0);
109 2         31 $self->{'_AOL_no_results_found'} = 1;
110 2         13 return 0;
111             }
112              
113             sub parse_tree
114             {
115 2     2 1 12850569 my ($self, $tree) = @_;
116              
117 2 50       24 if ($self->{'_AOL_no_results_found'})
118             {
119 0         0 return 0;
120             }
121              
122 2 50       11 if ($self->{'_AOL_first_retrieve_call'})
123             {
124 2         8 $self->{'_AOL_first_retrieve_call'} = undef;
125              
126 2         30 my $nohit_div = $tree->look_down("_tag", "div", "class", "NH");
127              
128 2 100       7718 if (defined($nohit_div))
129             {
130 1 50 33     7 if (($nohit_div->as_text() =~ /Your search for/) &&
131             ($nohit_div->as_text() =~ /returned no results\./)
132             )
133             {
134 1         441 return $self->_no_hits();
135             }
136             }
137              
138 1         7 my $wr_div = $tree->look_down("_tag", "div", "class", "BB");
139              
140 1 50       5247 if (!defined($wr_div))
141             {
142 1         7 return $self->_no_hits();
143             }
144              
145             # A word separator that includes whitespace and   (\x{a0}.
146 0           my $word_sep = qr/[\s\x{a0}]+/;
147              
148 0 0         if (my ($n) =
149             (
150             $wr_div->as_text() =~
151             m/of${word_sep}about${word_sep}([\d,]+)/
152             )
153             )
154             {
155 0           $n =~ tr/,//d;
156 0           $self->approximate_result_count($n);
157             }
158             }
159              
160             =begin Removed
161              
162             my @h1_divs = $tree->look_down("_tag", "div", "class", "h1");
163             my $requested_div;
164             foreach my $div (@h1_divs)
165             {
166             my $h1 = $div->look_down("_tag", "h1");
167             if ($h1->as_text() eq "web results")
168             {
169             $requested_div = $div;
170             last;
171             }
172             }
173             if (!defined($requested_div))
174             {
175             die "Could not find div. Please report the error to the author of the module.";
176             }
177              
178             my $r_head_div = $requested_div->parent();
179             my $r_web_div = $r_head_div->parent();
180              
181             =end Removed
182              
183             =cut
184              
185 0           my $r_web_div = $tree->look_down("_tag", "ul", "content", "MSL");
186 0           my @results_divs = $r_web_div->look_down("_tag", "li", "about", qr{^r\d+$});
187 0           my $hits_found = 0;
188 0           foreach my $result (@results_divs)
189             {
190 0 0         if ($result->attr('about') !~ m/^r(\d+)$/)
191             {
192 0           die "Broken Parsing. Please contact the author to fix it.";
193             }
194 0           my $id_num = $1;
195 0           my $desc_tag = $result->look_down("_tag", "p", "property", "f:desc");
196 0           my $a_tag = $result->look_down("_tag", "a", "class", "find");
197 0           my $hit = WWW::SearchResult->new();
198 0           $hit->add_url($a_tag->attr("href"));
199 0           $hit->description($desc_tag->as_text());
200 0           $hit->title($a_tag->as_text());
201 0           push @{$self->{'cache'}}, $hit;
  0            
202 0           $hits_found++;
203             }
204              
205             # Get the next URL
206             {
207 0           my $span_next_page = $tree->look_down("_tag", "span", "class", "gspPageNext");
  0            
208 0           my @a_tags = $span_next_page->look_down("_tag", "a");
209             # The reverse() is there because it seems the "next" link is at
210             # the end.
211 0           foreach my $a_tag (reverse(@a_tags))
212             {
213 0 0         if ($a_tag->as_text() =~ "Next")
214             {
215             $self->{'_next_url'} =
216             $self->absurl(
217 0           $self->{'_prev_url'},
218             $a_tag->attr('href')
219             );
220 0           last;
221             }
222             }
223             }
224 0           return $hits_found;
225             }
226              
227              
228             =begin Removed
229              
230             =head2 preprocess_results_page()
231              
232             The purpose of this function was to decode the HTML text as returned by
233             search.aol.com as UTF-8. But it seems recent versions of WWW::Search already
234             have a similar mechanism.
235              
236             sub preprocess_results_page
237             {
238             my $self = shift;
239             my $contents = shift;
240              
241             return decode('UTF-8', $contents);
242             }
243              
244             =end Removed
245              
246             =cut
247              
248             =head1 AUTHOR
249              
250             Shlomi Fish, L .
251              
252             Funded by L and
253             L.
254              
255             =head1 BUGS
256              
257             Please report any bugs or feature requests to
258             C, or through the web interface at
259             L.
260             I will be notified, and then you'll automatically be notified of progress on
261             your bug as I make changes.
262              
263             =head1 ACKNOWLEDGEMENTS
264              
265             Funded by L and
266             L.
267              
268             =head1 DEVELOPMENT
269              
270             Source code is version-controlled in a Subversion repository in Berlios:
271              
272             L
273              
274             One can find the most up-to-date version there.
275              
276             =head1 COPYRIGHT & LICENSE
277              
278             Copyright 2006 Shlomi Fish, all rights reserved.
279              
280             This program is released under the following license: MIT X11 (a BSD-style
281             license).
282              
283             =cut
284              
285             1; # End of WWW::Search::AOL