&pgid;
方法が見当たらなかったので、作りました。
http://okra.ark-web.jp/~konuma/cgi-bin/search.cgi
#blikimore
**どうやって使うの? [#h179b1c4]
-上記のページに検索フォームがあるので、そこで検索します。
-すると、はてなでブックマークされている数のランキングが表示されます。
-ランキングの対象となるのは、はてなで検索をおこなったときに上位100までに表示されるページのみです。
***例えばこんな検索ができます。 [#z8198fb8]
-rubyについて書いてあるページで、最もブックマークされているのはどこ?
http://okra.ark-web.jp/~konuma/cgi-bin/search.cgi?keyword=ruby
-www.ark-web.jpにあるページで、最もブックマークされているのはどこ?
http://okra.ark-web.jp/~konuma/cgi-bin/search.cgi?keyword=site%3Awww.ark-web.jp
**中身どうなってんの? [#y5f01b09]
***概要 [#occ04723]
-rubyです。
-はてなの検索結果からスクレイピングしています。
http://www.hatena.ne.jp/
-志田さんの作った↓を参考にしています。
[[YouTube検索結果をスクレイピングして勝手API化]]
--//参考にしているというか、大部分コピーです。。。
***詳細 [#k0ac4317]
-このサービスは以下の三つのファイルから成り立ってます
search.cgi -- 表示部分
Hatena/SearchResultScraper.rb -- 検索およびスクレイピングをする部分
Hatena/page.rb -- 検索結果の1ページあたりのデータを保持する部分
そんなに長いコードではないので、全部掲載します。
-''search.cgi''
#!/usr/bin/ruby
require 'cgi'
require 'Hatena/SearchResultScraper'
require 'Hatena/page'
require 'kconv'
#はてなでの検索結果を取得する。
def scrape keyword
scraper = Hatena::SearchResultScraper.new(Kconv.toutf8(keyword), 10)
scraper.open
pages = scraper.order_by_bookmark_count
end
#検索結果を表示する
def print_pages pages
pages.each do |page|
print "<a href="#{page.url}">#{page.title}</a> <strong><a href="http://b.hatena.ne.jp/entry/#{page.url}">#{page.bookmark_count}</a></strong><br>"
end
end
print "Content-type: text/html\n\n"
cgi = CGI.new
keyword = cgi['keyword']
print <<EOS
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC_JP">
<title>form</title>
</head>
<body>
<form action="./search.cgi" method="get" charset=UTF-8">
<input name="keyword" value="#{keyword}">
<input type="submit" value="Search">
</form>
EOS
print_pages(scrape(keyword)) unless keyword.empty?
print <<EOS
</body>
</html>
EOS
-''Hatena/SearchResultScraper.rb''
require 'open-uri'
require 'cgi'
require 'rubygems'
require 'hpricot'
require 'Hatena/page'
module Hatena
class SearchResultScraper
@@search_base_url = "http://search.hatena.ne.jp/search?ie=utf8&word="
def initialize keyword, count = 10
@keyword = keyword
@count = count
end
#URLを開き、検索をおこなう。@countで指定された回数だけ検索結果を読み込む
def open
@pages = []
@count.times do |i|
page = open_page(i+1)
break if page.size == 0
@pages.concat(page)
end
@pages
end
#ブックマーク件数でソートする。
def order_by_bookmark_count
@pages.sort!
@pages.reverse!
end
private
#page番目の検索結果をスクレイピングする
def open_page page
url = @@search_base_url + CGI.escape(@keyword) + "&page=" + CGI.escape(page.to_s)
html = Kernel.open(url).read
replace_document_write_javascript(html)
scrape(Hpricot.parse(html))
end
#検索結果のページをスクレイピングする
def scrape result
pages = []
result.search("div.hatena-search-result-item").each do |page_html|
page = Hatena::Page.new
page.title = scrape_title(page_html)
page.url = scrape_url(page_html)
page.bookmark_count = scrape_bookmark_count(page_html)
pages << page
end
pages
end
#邪魔なjavascriptの文字列を置換する
def replace_document_write_javascript html
html.gsub!(%r{<script language="javascript" type="text/javascript">.*?document.write\('(.*?)'\).*?</script>}m, '\1')
end
#タイトルをスクレイピングする
def scrape_title page_html
page_html.search("//h3//a").inner_html
end
#URLをスクレイピングする
def scrape_url page_html
page_html.search("//h3").inner_html.sub(/<a href="([^"]+)">.+/, '\1')
end
#ブックマーク件数をスクレイピングする
def scrape_bookmark_count page_html
page_html.search("//span[@class='users']").inner_html.sub(/(<.+>)?<a.*?>(\d+) users?<\/a>(<\/.+>)?/, '\2')
end
end
end
-''Hatena/page.rb''
module Hatena
class Page
attr_accessor :url
attr_accessor :title
attr_accessor :bookmark_count
#ブックマーク件数で比較する(ブックマーク件数でソートするときのために)
def <=> another
self.bookmark_count.to_i <=> another.bookmark_count.to_i
end
end
end
**制限事項 [#qfe584fe]
-日本語で検索できません。
--%%いずれ対応する予定です。%%対応しました。
-遅いです。
--はてなの検索画面を10ページ分もスクレイピングしているので。。。
-ランキングは正確じゃないかも
--ランキングの対象となるのが「はてなの検索結果の上位100まで」なので、それより下の順位にあるページが無視されています。
**コメント [#b76cef3e]
- ブックマーク数のところをリンクにして、はてなブックマークページ(って言うのかな?)へ飛ぶようにしました。 -- [[小沼]] &new{2007-01-30 (火) 12:14:39};
#comment
#blikifooter(小沼)
tag: [[WebAPI>tag/WebAPI]], [[スクレイピング>tag/スクレイピング]]