File Coverage

blib/lib/WWW/Scraper/ISBN/ORA_Driver.pm
Criterion Covered Total %
statement 24 68 35.2
branch 0 28 0.0
condition 0 17 0.0
subroutine 8 9 88.8
pod 1 1 100.0
total 33 123 26.8


line stmt bran cond sub pod time code
1             package WWW::Scraper::ISBN::ORA_Driver;
2              
3 5     5   285917 use strict;
  5         39  
  5         154  
4 5     5   26 use warnings;
  5         9  
  5         180  
5              
6 5     5   30 use vars qw($VERSION @ISA);
  5         9  
  5         455  
7             $VERSION = '0.23';
8              
9             #--------------------------------------------------------------------------
10              
11             =head1 NAME
12              
13             WWW::Scraper::ISBN::ORA_Driver - Search driver for O'Reilly Media's online catalog.
14              
15             =head1 SYNOPSIS
16              
17             See parent class documentation (L)
18              
19             =head1 DESCRIPTION
20              
21             Searches for book information from the O'Reilly Media's online catalog.
22              
23             =cut
24              
25             #--------------------------------------------------------------------------
26              
27             ###########################################################################
28             # Inheritence
29              
30 5     5   65 use base qw(WWW::Scraper::ISBN::Driver);
  5         11  
  5         2589  
31              
32             ###########################################################################
33             # Modules
34              
35 5     5   9117 use WWW::Mechanize;
  5         770604  
  5         256  
36              
37             ###########################################################################
38             # Constants
39              
40 5     5   51 use constant ORA => 'https://www.oreilly.com';
  5         12  
  5         385  
41 5     5   35 use constant SEARCH => 'https://search.oreilly.com';
  5         10  
  5         227  
42 5     5   31 use constant QUERY => '?submit.x=17&submit.y=8&q=%s';
  5         10  
  5         3594  
43              
44             #--------------------------------------------------------------------------
45              
46             ###########################################################################
47             # Public Interface
48              
49             =head1 METHODS
50              
51             =over 4
52              
53             =item C
54              
55             Creates a query string, then passes the appropriate form fields to the
56             O'Reilly Media server.
57              
58             The returned page should be the correct catalog page for that ISBN. If not the
59             function returns zero and allows the next driver in the chain to have a go. If
60             a valid page is returned, the following fields are returned via the book hash:
61              
62             isbn (now returns isbn13)
63             isbn10
64             isbn13
65             ean13 (industry name)
66             author
67             title
68             book_link
69             image_link
70             thumb_link
71             description
72             pubdate
73             publisher
74             binding (if known)
75             pages (if known)
76             weight (if known) (in grammes)
77             width (if known) (in millimetres)
78             height (if known) (in millimetres)
79              
80             The book_link and image_link refer back to the O'Reilly US website.
81              
82             =back
83              
84             =cut
85              
86             sub search {
87 0     0 1   my $self = shift;
88 0           my $isbn = shift;
89 0           $self->found(0);
90 0           $self->book(undef);
91              
92 0           my $mech = WWW::Mechanize->new();
93 0           $mech->agent_alias( 'Linux Mozilla' );
94              
95 0           my $url = SEARCH . sprintf(QUERY,$isbn);
96 0           eval { $mech->get( $url ) };
  0            
97 0 0 0       return $self->handler("O'Reilly Media website appears to be unavailable.")
      0        
98             if($@ || !$mech->success() || !$mech->content());
99              
100             # The Search Results page
101 0           my $content = $mech->content();
102 0           my ($book) = $content =~ m!
\s*

\s*

103              
104 0 0         unless(defined $book) {
105             #print STDERR "\n#url=$url\n";
106             #print STDERR "\n#content=".$mech->content();
107 0           return $self->handler("Could not extract data from the O'Reilly Media search page [".($mech->uri())."].");
108             }
109              
110 0           eval { $mech->get( $book ) };
  0            
111 0 0 0       return $self->handler("O'Reilly Media website appears to be unavailable.")
      0        
112             if($@ || !$mech->success() || !$mech->content());
113              
114 0           my $html = $mech->content();
115 0           my $data = {};
116              
117 0           for my $name ('book.isbn','ean','target','reference','isbn','graphic','graphic_medium','graphic_large','book_title','author','keywords','description','date') {
118 0 0         if($html =~ m!!i) {
    0          
119 0           $data->{$name} = $1;
120             } elsif($html =~ m!!i) {
121 0           $data->{$name} = $1;
122             }
123             }
124              
125             #my (@isbns) = split(',',$data->{target});
126 0 0         if($data->{target}) {
127 0           for my $isbn ( split(',',$data->{target}) ) {
128 0           $isbn =~ s/\D+//g;
129 0 0         next unless($isbn);
130 0 0         $data->{isbn10} = $isbn if(length($isbn) == 10);
131 0 0         $data->{isbn13} = $isbn if(length($isbn) == 13);
132             }
133             }
134              
135             #($data->{isbn13},$data->{isbn10}) = $html =~ m!
(?:Print )?ISBN:
]+>([\d-]+)\s*
\| ISBN 10:
([\d-]+)
!;
136 0           ($data->{pages}) = $html =~ m!

Pages:\s*(\d+)\s*

!;
137              
138 0           for ('graphic_medium','graphic_large') { # alternative graphic fields
139 0 0         next unless($data->{$_});
140 0   0       $data->{graphic} ||= $data->{$_};
141             }
142 0   0       $data->{graphic} ||= '';
143            
144              
145 0 0         unless(defined $data) {
146             #print STDERR "\n#url=$book\n";
147             #print STDERR "\n#content=".$mech->content();
148 0           return $self->handler("Could not extract data from the O'Reilly Media result page [".($mech->uri())."].");
149             }
150              
151             # trim top and tail
152 0 0         foreach (keys %$data) { next unless(defined $data->{$_});$data->{$_} =~ s/^\s+//;$data->{$_} =~ s/\s+$//; }
  0            
  0            
  0            
153              
154             my $bk = {
155             'ean13' => $data->{ean},
156             'isbn13' => $data->{ean},
157             'isbn10' => $data->{isbn10},
158             'isbn' => $data->{ean},
159             'author' => $data->{author},
160             'title' => $data->{book_title},
161             'book_link' => $mech->uri(),
162             'image_link' => ($data->{graphic} !~ /^http/ ? ORA : '') . $data->{graphic},
163             'thumb_link' => ($data->{graphic} !~ /^http/ ? ORA : '') . $data->{graphic},
164             'description' => $data->{description},
165             'pubdate' => $data->{date},
166             'publisher' => q!O'Reilly Media!,
167             'binding' => $data->{binding},
168             'pages' => $data->{pages},
169             'weight' => $data->{weight},
170             'width' => $data->{width},
171             'height' => $data->{height}
172 0 0         };
    0          
173 0           $self->book($bk);
174 0           $self->found(1);
175 0           return $self->book;
176             }
177              
178             1;
179              
180             __END__