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) #=> 出力結果は量が多いためカット
取得し、パースもできました。
しかし、目的のタグのtitle
やhref
(URL)といった属性を抽出する方法がわかりません。
NokogiriオブジェクトはXpath
やcssセレクタ
で要素を指定して抽出できるそうなのでその要素を探します。
chrome で解析
スクレイピングを行うために、Google Chromeデベロッパーツールを使い、抽出の際目印になりそうな要素を探していきます。
chrome上でF12
若しくは⌘+option+i
で起動します。
左のマウスカーソルのようなアイコンをクリックすると、マウスカーソルの下にあるテキストや画像がhtmlのどの部分に該当するかわかります。 タイトルとURLが抽出できそうなclassが見つかりました。
スクレイピング
html取得の項目のコードの続き
#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
Xpath
とcssセレクタ
はとてもはまりました。
調べてもクリティカルな情報が見つからず、他のブログのサンプルコード結果から予測して試行錯誤しながらXpath
やcssセレクタ
を書いていました。
特にハッシュのように要素を抽出する方法に巡り合えなくて、代替案として文字列に変換して正規表現で抽出するコードを書いたりもしました。