プログラミング学習メモ

RubyとRuby on Rails等

nokogiriでスクレイピング

今回はいつものドキュメントの焼き直しみたいなのではなく、実際に作ってみたことを書いてみようと思います。

目標

はてなブックマークのテクノロジー部門ランキングをスクレイピングし、タイトルとURLを拾う

html取得

まずhtmlを取得してみます。

require 'nokogiri' #スクレイピングのライブラリ
require 'open-uri' #urlを開くライブラリ

charset = nil
#htmlと文字コードを取得
html = open(url) do |f| 
  charset = f.charset
  f.read 
end

#取得したhtmlを操作しやすいNokogiriオブジェクトにパース
 doc = Nokogiri::HTML.parse(html, nil, charset)


#=> 出力結果は量が多いためカット

取得し、パースもできました。 しかし、目的のタグのtitlehref(URL)といった属性を抽出する方法がわかりません。

NokogiriオブジェクトはXpathcssセレクタで要素を指定して抽出できるそうなのでその要素を探します。

chrome で解析

スクレイピングを行うために、Google Chromeデベロッパーツールを使い、抽出の際目印になりそうな要素を探していきます。

chrome上でF12若しくは⌘+option+iで起動します。

左のマウスカーソルのようなアイコンをクリックすると、マウスカーソルの下にあるテキストや画像がhtmlのどの部分に該当するかわかります。 f:id:zoo_web:20191129005547p:plain タイトルとURLが抽出できそうなclassが見つかりました。

スクレイピング

html取得の項目のコードの続き

先ほど得た要素をXpathcssセレクタで記述します。

#entrylist-contents-titleというclassを持つh3タグの中のaタグという意味
x = '//h3 [@class="entrylist-contents-title"]/a'
c = 'h3.entrylist-contents-title a'

これを用いて抽出したaタグを一つずつ処理します。

#Xpath
doc.xpath(x).each do |node|
  puts node[:title]
  puts node[:href]
end

#cssセレクタ
doc.css(c).each do |node|
  puts node[:title]
  puts node[:href]
end

#出力は同じ。繰り返しの1番目のみ。
#=>韓国トップの囲碁棋士引退「努力してもAIには勝てない」 | NHKニュース
#=>https://www3.nhk.or.jp/news/html/20191129/k10012195501000.html

Xpathcssセレクタはとてもはまりました。
調べてもクリティカルな情報が見つからず、他のブログのサンプルコード結果から予測して試行錯誤しながらXpathcssセレクタを書いていました。
特にハッシュのように要素を抽出する方法に巡り合えなくて、代替案として文字列に変換して正規表現で抽出するコードを書いたりもしました。

参考
スクレイピングエンジニアなら知っておきたいNokogiriの使い方8選