Wedata の Database: ISBN Scraper をテストするスクリプト

確実に私しか使わないと思うけど…。

Item - データベース: ISBN Scraper - wedata に登録してある ISBN を抽出する XPath をテストするスクリプトを書いた。

  1. Wedata からデータ(URL, XPath, SampleURL, SampleISBN)を取得
  2. SampleURL なサイトの HTML を取得
  3. HTML から XPath を評価して ISBN を取得
  4. ISBN と SampleISBN が同じであるかチェック
  5. 結果を YAML 形式で出力
  6. PlaggerYAML から RSS に変換して Gmail する

これを毎朝 cron で実行させておくと、↓こんなメールが届くのでながめてにやにやすることができる!


#!/usr/bin/perl
# isbn scraper checker
use strict;
use warnings;

use DateTime;
use LWP::UserAgent;
use WebService::Wedata;
use XML::LibXML;
use XML::LibXML::XPathContext;
use YAML;

my $wedata = WebService::Wedata->new;
my $database = $wedata->get_database('ISBN Scraper');
my $items = $database->get_items;

my $ua = LWP::UserAgent->new;
$ua->agent('Mozilla/5.0');
my $parser = XML::LibXML->new;
$parser->recover_silently(1);

my $total = 0;
my @entry;
foreach my $item (@{$items}) {
  my $data = $item->{data};
  my $url = $data->{exampleUrl};
  next
    unless $url;

  my @errors;
  ++$total;

  my $resp = $ua->get($url);
  if ($resp->is_success) {
    my $doc = $parser->parse_html_string($resp->content);
    my $xpc = XML::LibXML::XPathContext->new($doc);

    foreach my $key ('Isbn10', 'Isbn13') {
      my $xp = $data->{lc $key};
      my $ex = $data->{'example' . $key};
      next
        unless defined $ex && defined $xp;

      my $isbn = $xpc->findvalue($xp);
      next
        if $isbn eq $ex;

      push @errors,
        sprintf
          '<ul><li>cause: invalid xpath?</li>' .
          '<li>xpath: %s</li><li>value: %s</li><li>isbn: %s</li></ul>',
          $xp, $isbn, $ex;
    }

  } else {
    push @errors,
      sprintf '<ul><li>cause: %s</li></ul>', $resp->status_line;
  }

  next
    unless @errors;

  push @entry, {
    title => $item->{name},
    link => $item->{resource_url},
    body => join '<br>', @errors
  };
}

my $res = {
  entry => @entry ? \@entry : [{ title => 'no error!'}],
  title => sprintf
    'ISBN Scraper Daily Report(%s) %s %d/%d',
    DateTime->now->ymd('/'), @entry ? 'NG' : 'OK', $total - scalar @entry, $total
};
print Dump $res;
plugins:
  - module: Subscription::Config
    config:
      feed:
        - url: script:/path/to/check-isbnscraper.pl
  - module: CustomFeed::Script
  - module: Publish::Gmail
    config:
      mailto: xxxxx@gmail.com
      mailfrom: xxxxx@gmail.com
      mailroute:
        via: smtp_tls
        host: smtp.gmail.com:587
        username: xxxxx
        password: xxxxx