いろんなサイトから ISBN を抽出するグリモンのテスト

2008/05/22 追記
via id:hetappiさんのISBNのグリモンを少し弄った。 - tyoro.exe
tyoro さんに指摘してもらって wedata から json 形式で取得したときの Content-Type を text/javascript から application/json に修正しました。ありがとです。
このまえ少し止まってた時に変わったのかな…。



wedata にとりあえず作って1か月ほど放置していた Item - データベース: ISBN Scraper - wedata 。CrossBookSearch のソース中にだーっと書いてあった ISBN を抽出する XPathWiki で管理することで、編集を容易にし他のスクリプトなどでも使えるようになります。きっと。


とりあえずテストグリモンでは Document もしくは http な URL 文字列から ISBN をゲットできるようにした。

var sc = new ISBNScraper;
sc.scrape(document, function(isbn) {
  if (isbn)
    console.dir(isbn);
});
sc.scrape('http://www.oreilly.co.jp/books/9784873113654/', function(isbn) {
  if (isbn)
    console.dir(isbn);
});
isbn10 "4873113636"
isbn13 "9784873113630"

isbn10 ""
isbn13 "9784873113654"

まだ wedata には Amazonオライリーしかないけど、http://coderepos.org/share/browser/lang/javascript/userscripts/crossbooksearch.user.js? にいっぱいあるので誰か(ry。

// ==UserScript==
// @name           TestISBNScraper
// @namespace      http://d.hatena.ne.jp/hetappi
// @include        *
// ==/UserScript==

var sc = new ISBNScraper;
sc.scrape(document, function(isbn) {
  if (isbn)
    console.dir(isbn);
});
sc.scrape('http://www.oreilly.co.jp/books/9784873113654/', function(isbn) {
  if (isbn)
    console.dir(isbn);
});

function ISBNScraper() {
  return {
    _getSiteInfo: function(callback) {
      var cache = eval(GM_getValue('cache'));
      if (cache && cache.expire > new Date().getTime()) {
        callback(cache.siteinfo);

      } else {
        new GMUtil().get('http://wedata.net/databases/isbn%20scraper/items.json', function(resp) {
          if (resp && resp.response.body.type == 'json') {
            var items = resp.response.body.json;
            var cacheNew = {
              siteinfo: items,
              expire: new Date(new Date().getTime() + 24 * 60 * 60 * 1000)
            };
            GM_setValue('cache', uneval(cacheNew));
            callback(items);
          } else {
            callback(cache ? cache.siteinfo : null);
          }
        });
      }
    },

    _getIsbn: function(doc, url, items) {
      for (var i = 0, m = items.length; i < m; ++i) {
        if (!new RegExp(items[i].data.url).test(url))
          continue;
        var isbn = {};
        if (items[i].data.isbn10)
          isbn.isbn10 = doc.evaluate(
            items[i].data.isbn10, doc, null, XPathResult.STRING_TYPE, null).stringValue;
        if (items[i].data.isbn13)
          isbn.isbn13 = doc.evaluate(
            items[i].data.isbn13, doc, null, XPathResult.STRING_TYPE, null).stringValue;
        return isbn;
      }
      return null;
    },

    scrape: function(src, callback) {
      if (!src) {
        callback(null);
        return;
      }

      var self = this;
      self._getSiteInfo(function(items) {
        if (!items) {
          callback(null);
        } else if (typeof src == 'string' && new RegExp('^https?://').test(src)) {
          new GMUtil().get(src, function(resp) {
            callback(
              resp ? self._getIsbn(resp.response.body.document, src, items) : null);
          });
        } else if (typeof src == 'object' && new GMUtil().instanceof(src, Document)) {
          callback(self._getIsbn(src, src.location.href, items));
        } else {
          callback(null);
        }
      });
    }
  };
}
続きを読む