File Coverage

blib/lib/WWW/Scraper/ISBN/Blackwell_Driver.pm
Criterion Covered Total %
statement 21 70 30.0
branch 0 18 0.0
condition 0 18 0.0
subroutine 7 8 87.5
pod 1 1 100.0
total 29 115 25.2


\s*\s*!si; \s*!si; \s*(\d+)g!si; \s*!si; \s*!si;
line stmt bran cond sub pod time code
1             package WWW::Scraper::ISBN::Blackwell_Driver;
2              
3 5     5   288689 use strict;
  5         40  
  5         154  
4 5     5   29 use warnings;
  5         9  
  5         198  
5              
6 5     5   33 use vars qw($VERSION @ISA);
  5         18  
  5         467  
7             $VERSION = '1.00';
8              
9             #--------------------------------------------------------------------------
10              
11             =head1 NAME
12              
13             WWW::Scraper::ISBN::Blackwell_Driver - Search driver for Blackwell's online book catalog.
14              
15             =head1 SYNOPSIS
16              
17             See parent class documentation (L)
18              
19             =head1 DESCRIPTION
20              
21             Searches for book information from Blackwell's online book catalog.
22              
23             =cut
24              
25             #--------------------------------------------------------------------------
26              
27             ###########################################################################
28             # Inheritence
29              
30 5     5   38 use base qw(WWW::Scraper::ISBN::Driver);
  5         11  
  5         2737  
31              
32             ###########################################################################
33             # Modules
34              
35 5     5   9477 use WWW::Mechanize;
  5         774512  
  5         274  
36              
37             ###########################################################################
38             # Constants
39              
40 5     5   54 use constant REFERER => 'http://bookshop.blackwell.co.uk';
  5         14  
  5         413  
41 5     5   34 use constant SEARCH => 'http://bookshop.blackwell.co.uk/jsp/search_results.jsp?wcp=1&quicksearch=1&cntType=&searchType=keywords&searchData=%s&x=10&y=10';
  5         14  
  5         4720  
42              
43             #--------------------------------------------------------------------------
44              
45             ###########################################################################
46             # Public Interface
47              
48             =head1 METHODS
49              
50             =over 4
51              
52             =item C
53              
54             Creates a query string, then passes the appropriate form fields to the
55             Blackwell server.
56              
57             The returned page should be the correct catalog page for that ISBN. If not the
58             function returns zero and allows the next driver in the chain to have a go. If
59             a valid page is returned, the following fields are returned via the book hash:
60              
61             isbn (now returns isbn13)
62             isbn10
63             isbn13
64             ean13 (industry name)
65             author
66             title
67             book_link
68             image_link
69             thumb_link
70             description
71             pubdate
72             publisher
73             binding (if known)
74             weight (if known) (in grammes)
75             width (if known) (in millimetres)
76             height (if known) (in millimetres)
77              
78             The book_link, image_link and thumb_link all refer back to the Blackwell website.
79              
80             =back
81              
82             =cut
83              
84             sub search {
85 0     0 1   my $self = shift;
86 0           my $isbn = shift;
87 0           $self->found(0);
88 0           $self->book(undef);
89              
90             # validate and convert into EAN13 format
91 0           my $ean = $self->convert_to_ean13($isbn);
92 0 0 0       return $self->handler("Invalid ISBN specified")
      0        
      0        
      0        
93             if(!$ean || (length $isbn == 13 && $isbn ne $ean)
94             || (length $isbn == 10 && $isbn ne $self->convert_to_isbn10($ean)));
95 0           my $isbn10 = $self->convert_to_isbn10($ean);
96              
97 0           my $mech = WWW::Mechanize->new();
98 0           $mech->agent_alias( 'Windows IE 6' );
99 0           $mech->add_header( 'Accept-Encoding' => undef );
100              
101 0           my $search = sprintf SEARCH , $ean;
102             #print STDERR "\n# search=[$search]\n";
103              
104 0           eval { $mech->get( $search ) };
  0            
105 0 0 0       return $self->handler("Blackwell's website appears to be unavailable.")
      0        
106             if($@ || !$mech->success() || !$mech->content());
107              
108             # The Book page
109 0           my $html = $mech->content();
110              
111 0 0         return $self->handler("Blackwell's website appears to be unavailable.")
112             if($html =~ m!Blocked IP Address due to Suspicious Activity!si);
113              
114 0 0         return $self->handler("Failed to find that book on the Blackwell website. [$isbn]")
115             if($html =~ m!Sorry, there are no results for!si);
116            
117 0           $html =~ s/&/&/g;
118 0           $html =~ s/ / /g;
119 0           $html =~ s/–/-/g;
120             #print STDERR "\n# html=[\n$html\n]\n";
121              
122 0           my $data;
123 0           ($data->{isbn13}) = $html =~ m!!si;
124 0           ($data->{title}) = $html =~ m!!si;
125 0           ($data->{author}) = $html =~ m!

]*>\s*]+>([^<]+)!si;

126 0           ($data->{binding}) = $html =~ m!

\s*([^<\(]+)!si;

127 0           ($data->{publisher}) = $html =~ m!Publisher:]*>\s*]+>\s*]+>([^<]+)\s*!si;
128 0           ($data->{pubdate}) = $html =~ m!Pub date:
129 0           ($data->{description}) = $html =~ m!!si;
130 0           ($data->{pages}) = $html =~ m!Number of pages:(\d+)
131 0           ($data->{weight}) = $html =~ m!Weight:
132 0           ($data->{height}) = $html =~ m!Height:(\d+)mm
133 0           ($data->{width}) = $html =~ m!Width:(\d+)mm
134 0           ($data->{image}) = $html =~ m!!si;
135              
136 0 0         $data->{image} =~ s!https:///!https://bookshop.blackwell.co.uk/! if($data->{image});
137 0           $data->{thumb} = $data->{image};
138 0           $data->{isbn10} = $isbn10;
139 0 0         $data->{author} =~ s/\s*\(author\)//si if($data->{author});
140 0 0         $data->{publisher} =~ s/�?39;/'/g if($data->{publisher});
141              
142             #use Data::Dumper;
143             #print STDERR "\n# " . Dumper($data);
144              
145 0 0         return $self->handler("Could not extract data from the Blackwell result page.")
146             unless(defined $data);
147              
148             # trim top and tail
149 0           foreach (keys %$data) {
150 0 0         next unless(defined $data->{$_});
151 0           $data->{$_} =~ s! ! !g;
152 0           $data->{$_} =~ s/^\s+//;
153 0           $data->{$_} =~ s/\s+$//;
154             }
155              
156 0           my $url = $mech->uri();
157              
158             my $bk = {
159             'ean13' => $data->{isbn13},
160             'isbn13' => $data->{isbn13},
161             'isbn10' => $data->{isbn10},
162             'isbn' => $data->{isbn13},
163             'author' => $data->{author},
164             'title' => $data->{title},
165             'book_link' => $url,
166             'image_link' => $data->{image},
167             'thumb_link' => $data->{thumb},
168             'description' => $data->{description},
169             'pubdate' => $data->{pubdate},
170             'publisher' => $data->{publisher},
171             'binding' => $data->{binding},
172             'pages' => $data->{pages},
173             'weight' => $data->{weight},
174             'height' => $data->{height},
175             'width' => $data->{width},
176 0           'html' => $html
177             };
178              
179             #use Data::Dumper;
180             #print STDERR "\n# book=".Dumper($bk);
181              
182 0           $self->book($bk);
183 0           $self->found(1);
184 0           return $self->book;
185             }
186              
187             1;
188              
189             __END__