Rubyでは、Nokogiri+CSSセレクタで簡単にスクレイピングすることが出来ます。
TABLE(TD)タグを例に解説します。
なるほど。
Rubyを使って、軽く作ってみましょう。
簡単なのはRubyならNokogiri+cssセレクタ
下記はRubyの、Nokogiri+cssセレクタで、テキストを抽出する例です。
参考ソース
●test_nokogiri_table.rb
require 'nokogiri' require 'open-uri' src_url = "任意のURL" html = open(src_url).read doc = Nokogiri::HTML.parse(html) table = doc.css('table') # 複数取得 table.each_with_index do |tb, ib| puts "●テーブル#{ib+1}個目" table_data = [] # この段階ではまだ1次元配列 tb.css('tr:has(td)').each_with_index do |tr, ir| table_data[ir] = [] # 配列の要素単位に配列を作成する(二次元化) tr.css('td').each_with_index do |td, id| table_data[ir][id] = td.text.strip end end pp table_data end
実行
ruby test_nokogiri_table.rb
解説
参考ソースではopen-uriを使いましたが、Mechanize等でもOKです。
私の実行環境ではhttpsでも行けました。
Nokogiriであれば、CSSセレクタを使用して、簡単にスクレイピングできます。
CSSセレクタとは、CSSの文法を流用することにより、HTMLの中の特定の情報を取得することができる仕組みです。
HTMLエンジニアやWebデザイナーなら、一度はChromeでF12からElementsタブをクリックして、「div.hoge」や「#foo」などで特定のclassやidなどの値の変化や、表示の挙動を調べたことがありますよね?
アレがこれです。
ループを3重(TABLE、TR、TD)にして、2次元配列(TR、TD)にセットしています。
Rubyは他の言語と異なり、空の2次元配列の枠だけを一気に定義できないので、ループしながら2次元目を定義する必要があります。
Ruby独特の記述方法はそれくらいでしょうか。
doc.css('table')
だと複数のTABLEタグを持ってきます。
今回はループして全部のテーブルを取得するケースですが、殆どのニーズは特定のテーブルのみを持ってきたいでしょうから、TABLE配列の特定の要素(0から始まるので注意)からTR、TDのみのループに変更して使用してみてください。
(なので、2次元配列(TR、TD)にしています。)
tb.css('tr:has(td)')
で、TDタグで構成されているTRタグをセレクトします。
よって、上記例ではTHタグの行は取得しません。
単にデータだけ欲しい場合はいらないでしょうし。CSV化したい場合でも、ヘッダー表は自分で作ったほうが良いと思います。
td.text
はinnerTextなので、ボールドやイタリックやspan
といった装飾タグは除去されます。
strip
は他の言語で言うところのtrim()
です。Nokogiriでは付けなくても良かったかもしれませんが、念のため。
出来上がった2次元配列は?
スクレーピングした情報は、多くの場合、DB等にストックし、何らかの再利用を行うと思います。
まず、数値の場合はカンマ区切りのまま取得していますので、除去しないと、INSERT/UPDATE時にエラーとなるでしょう。
また、DBのカラムがDECIMAL属性で、桁数チェックが必要になる場合があれば、チェックして、エラーがあれば、DBを改善するなりしたほうが良いかと思います。
VARCHARの場合は文字数あるいはバイト数チェックでしょうか。文字数チェックで済ませれば楽でしょうね。
(Rubyはサロゲートペア対応していますので、可能な限り、サロゲートペアに対応しているDBを選択してください。)
最後に
他の言語をお使いの場合は、適宜移植してみてください。
(Nokogiriのようなものがあればいいですね。)
そんなパッケージは無いよ…といった場合は、下記の関連記事も参照ください。
それでは、また。