require 'html-parser' require 'formatter' require 'uri' # HTML中の書評(ISBN)を検出するクラス # class ReviewDetecter < HTMLParser # 書評の入れ物クラス # class Review attr_accessor :isbn, :reviewer, :url def initialize(isbn, url, reviewer) @isbn = isbn @url = url @reviewer = reviewer end # ISBNを数値のみにする。識別用に使うためのもの。 # def s_isbn @isbn.gsub(/[^0-9]+/,"") end end attr_reader :review_list # 初期化する。 # 第3引数は書評を書いた人を指定する場合。nilの場合はHTML中の # から検出する。 # def initialize(writer, url, reviewer=nil) super(writer) @url = url @reviewer = reviewer @review_list = {} @anchor = nil @anchor_name = nil end def do_meta(attrs) if !@reviewer if attrs.assoc("name").to_s.downcase == "author" @reviewer = attrs.assoc("content") end end end # 書評をリストに格納する # def regist_review(isbn) if @anchor_name review = Review.new(isbn, @url+"#"+@anchor_name, @reviewer) else review = Review.new(isbn, @url, @reviewer) end @review_list[review.s_isbn] = review end def anchor_bgn(href, name, type) isbn = lookup_isbn_by_href(href) if isbn regist_review(isbn) end @anchor = href if name @anchor_name = name end end def handle_data(data) isbn = lookup_isbn_by_text(data) if isbn regist_review(isbn) end end # href属性値の中からISBNを探す # def lookup_isbn_by_href(href) if %r|www.amazon.co.jp/exec/obidos/ASIN/([0-9][-0-9X]+)/|i =~ href return $1 elsif %r|www.bk1.co.jp/[^'"]*isbn=([0-9][-0-9X]+)|i =~ href return $1 end return nil end # 文字列の中からISBNを探す # def lookup_isbn_by_text(data) if %r|isbn[\s=:]?([0-9][-0-9X]+)|i =~ data return $1 end end ## for simple use class << self def detect(data, url) f = NullFormatter.new() parser = ReviewDetecter.new(f, url) parser.feed(data) list = parser.review_list parser.close() return list end end end if __FILE__ == $0 require 'net/http' Net::HTTP.version_1_2 data = nil url = URI.parse(ARGV[0]) http = Net::HTTP.new(url.host, url.port) http.start{ res, = http.get(url.path) data = res.body } list = ReviewDetecter.detect(data, ARGV[0]) p list end