&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>&nbsp;&nbsp;<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/スクレイピング]]

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

アークウェブのサービスやソリューションはこちら