はてブ検索で特定キーワードの特定のユーザーのコメントを取得する(スクレイピング) Rubyで

＊と思ったけれども今現在も使えるようだ。ゴニョゴニョしてる関係で旧ブックマーク画面を参照しているらしい。でも多分もう少ししたら消える。若干だけわかりやすくしてみた。（2017 8/22 15:00）

＊このスクレイピングははてなブックマークのUI変更により使えなくなりました（作った日:8/21 14:00くらい UIが変わった日:8/21 18:00くらい）悲しい
全てのユーザーが最初ページ内にないのでjavascriptなどが使えるphantomjsなどのヘッドレスブラウザを使う必要が出てきた。
まぁでも、人気コメとかだけでいいなら簡単な修正で使えるはず。

#準備

とりあえずruby使えるようにしましょう
[Ruby](https://www.ruby-lang.org/ja/)

```
$ ruby hello.rb
Hello World!
```

rubyだとNokogiriというのがメジャー？っぽいのでそれを利用。
[Nokogiriを使ったRubyスクレイピング [初心者向けチュートリアル]](http://morizyun.github.io/blog/ruby-nokogiri-scraping-tutorial/index.html)

```
$ gem install nokogiri
```

はてな？のトップページとかでHTML取得とかしようとしたら503エラーが出たので調べる。
どうやら、ユーザーエージェント偽装しないとエラーになるらしい。
[Nokogiriを使うときにでた503エラー](http://i101330.hatenablog.com/entry/2016/03/25/221337)
open時にオプションとしてユーザーエージェントを渡してやる

```
#ユーザーエージェント偽装しないとエラーになる
opt = {}
opt['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/XXXXXXXXXXXXX Safari/XXXXXX Vivaldi/XXXXXXXXXX'

html = open(url,opt) do |page|

end
```

コマンドラインからの引数の渡し方は簡単というか普通で、スペースごとにパラメータ渡せばARGV配列に入る。
[コマンドラインからデータを簡単入力！ Ruby ARGVとは？](http://media.tech-salon.com/ruby-argv-%E3%81%A8%E3%81%AF-%E8%A7%A3%E8%AA%AC/)

```
------
puts ARGV[0]
------

$ ruby argv.rb test-argv
test-argv
```

引数渡して日本語検索もしたいのでエンコード処理も追加。
[RubyでURLのエンコード、デコードをする| URI](http://mukaer.com/archives/2012/03/18/rubyurl_uri/)

#スクレイピング

とりあえずはてブの検索ページだとhttp://b.hatena.ne.jp/search/textでqに検索キーワードを渡すとそれに応じた一覧が表示される。
またusersに数値を指定してあげると最低ブックマーク数で検索が可能。
例えば下記URLだと50ユーザー以上がブックマークした[豊洲]というキーワードに引っかかる一覧が出てくる。
[http://b.hatena.ne.jp/search/text?q=豊洲&users=50](http://b.hatena.ne.jp/search/text?q=%E8%B1%8A%E6%B4%B2&users=50)

以上諸々を考慮して下記になる（一番最初にも言いましたが現在使えません）

```rb:ruby-scraping.rb
#!/usr/bin/env ruby
#-*- coding: utf-8 -*-

#webに接続するためのライブラリ
require "open-uri"
require "uri"
#クレイピングに使用するライブラリ
require "nokogiri"

target_text = URI.escape(ARGV[0])
target_usr = ARGV[1]
target_hatena_count = ARGV[2]

#ユーザーエージェント偽装しないとエラーになる
opt = {}
opt['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/XXXXXXXXXXXXX Safari/XXXXXX Vivaldi/XXXXXXXXXX'

url_users = ""

if !target_hatena_count.nil?
  url_users = "&users="+target_hatena_count
end

#はてブの検索
url = "http://b.hatena.ne.jp/search/text?q="+target_text+url_users

#取得するhtml用charset
charset = nil

html = open(url,opt) do |page|
  #charsetを自動で読み込み、取得
  charset = page.charset
  #中身を読む
  page.read
end

contents = Nokogiri::HTML.parse(html,nil,charset)

#検索結果を個別に取得
targetNodes = contents.css("li.search-result")
for result in targetNodes do
  #title
  title = result.css("h3 a")[0][:title]
  #該当の結果のはてブURLを取得
  hatenaBookmark = result.css("span.users a")[0][:href]
  targetUrl = "http://b.hatena.ne.jp/"+hatenaBookmark


  #該当はてブページのHTML取得
  targetCharset = nil
  hatebuHtml = open(targetUrl,opt) do |p|
    #charsetを自動で読み込み、取得
    targetCharset = p.charset
    #中身を読む
    p.read
  end

  #コンテンツの取得
  hatebuContents = Nokogiri::HTML.parse(hatebuHtml,nil,targetCharset)

  #該当のユーザーのコメントデータ取得
  #bookmark-user-u_mid
  puts "アドレス：" + targetUrl
  if !hatebuContents.css("li#bookmark-user-"+target_usr+" span.comment")[0].nil?
    hatebuComment = hatebuContents.css("li#bookmark-user-"+target_usr+" span.comment")[0].text
    puts "タイトル：" + title
    puts "コメント：" + hatebuComment
  #無ければなしを出力
  else
    puts "タイトル：" + title
    puts "コメント：なし"
  end
  puts "------------------------------------------------"

end
```

```
$ ruby scraping.rb キーワード ユーザー名 はてブ数
```

以上。