YAHOO!ニュースをスクレープしてみた

主要なホームページからJazzに関する情報を取り出すため、手始めにYAHOO!ニュースから表題とニュース本文を取り出すスクリプトを書いてみた。この手のツールやスクリプトは沢山あるんだけど、ゆくゆくは主要なサイトにも対応させていくため、ノウハウの蓄積のためにも自分自身で書いてみたという次第。コンテンツの読み込みに際しては1秒待つようにしています。サーバへの負荷軽減とそもそもYAHOO!自体が連続して読み込みを行うとすると404(コンテンツがない)という応答を返してくる対策を行っているようで、この回避のためです。

ちなみにこれを利用すれば、WindowsMobileマシンでニュース等の情報を持ち歩くことができます。このままでもEmacsの『アウトラインモード』でそれなりに便利に読めますし、rubyのRSSクラスを使用して本文もRSSに出力することで専用ビューワで読めるようになります。定額プランに入っていない場合は重宝するかもしれません。

ソースは以下のような感じ。40行くらいで動いたので結構生産性がいいんじゃないかな。実際作ってみたのは『Ruby on Rails』で使われている『ActiveRecord』というクラスを使ってDBへの保存まで対応しました。ちなみに3日分の海外のニュースをDBに保存したところ、3日間で400Kバイト程度になりました。年間計算で55Mバイト程度…ずっとDBを保持しておくのも後々楽しめるのかもしれない。例えば海外ニュースではニュースによっては『【インドシナ】~』や『<タイ>~』といった文字列が入っているので、これら文字列をキーにして『select』すれば、タイやインドシナのニュースが取り出せます。もちろん、もともとの目的であるジャズの情報を抜き出すのも同じ要領です。

MacOSでは1つの記事をDBに格納するまでに1秒くらいでした。つまりこの時間のほとんどが連続読みだし防止の1秒待ちの時間です。ところがサーバとして使用している『玄箱』では4~5秒かかりました。玄箱は搭載しているメモリが少ないため、CPU性能の影響というよりは、スワップなどによる影響が大きいのではないか、と推察しております。

うまく動いたし、ActiveRecordの使い方も少し分かったので、ジャズの情報を抜き出しDBに格納するスクリプトをどんどん書いていくぞ~。


#### YAHOO!ニュースの海外ニュースを標準出力に出力するサンプル
require ‘rubygems’
require ‘hpricot’
require ‘kconv’
require ‘jcode’
require ‘open-uri’
class YahooNews
def parse_news(uri)
sleep(1)
doc = Hpricot(open(uri))
self.parse_index(doc)
end
def parse_index(doc)
# ニュースの項目を取り出す
(doc/”div.list_ya/ul/li/a”).each do |a|
if a.attributes[’class’] != “yjS3″
sleep(1)
page_doc = Hpricot(open(a.attributes[’href’]))
parse_page(page_doc)
end
end
# 次のページを取得し、ニュースを処理する
(doc/”table/tr.yjS/td/a”).each do |a|
if a.inneer_text.toutf8 == “次のページ”
sleep(1)
next_doc = Hpricot(open(a.attributes[’href’]))
self.parse_index(next_doc)
end
end
end
def parse_page(doc)
title = doc.at(“div.yntop/h1.yjXL”).inner_text.toutf8
datestr = doc.at(“div.yntop/p.yjSt”).inner_text.toutf8.strip.gsub(/配信.*$/,’’)
contents = doc.at(“table/tr/td/div.yjMt”).inner_text.toutf8
puts “¥* #{title}(#{datestr})”
puts “#{contents}¥n”
end
end
news = YahooNews.new
news.parse_news(“http://headlines.yahoo.co.jp/hl?c=int&t=l”)