質問: Nokogiri::HTML.parse(html, nil, charset) doc.css('#post > div > header > h2 > a').each do |node| puts node.text end ``` この二つのサイトでは何がちがうのでしょうか? もしくは、私のやり方に不備があるのでしょうか?
回答: プログラムは自分が書いた通りにしか動きません。 上手く行かないのは基本的に自分のやり方が間違っていると思ってください。 nokogiriの前にスタイルシートの理解が不足しているように思います。 `#post`と`#post-9999`はまったく違うので、一致するはずがありませんよね? いきなり全部やろうとせずに1つずつやってみると良いです。 まずは、doc.css('#post') でどうなるか試そうと考えるわけです。 p doc.css('#post') を実行すると、id="post"の要素しかヒットしない事が分かるはずです。 この時点で、このアプローチ=やり方が間違っている事が分かります。 cssでは正規表現は使えません。 しかし、これはrubyなのでうまくcssの指定方法とrubyの機能を組み合わせばいいのです。 以下に例を示します。 例えば、こういう記事のdivがあったとして、まとめてループで処理したい場合、さきほどの説明で分かるように異なるIDをcssの指定では直接取れません。 ``` ... ... ... ``` そこで、まずはdiv全部を取得してループで回しながら、idがpost-数字にマッチするかどうかチェックして マッチしないものはスキップするという風にします。 ``` require 'nokogiri' html =< テスト ダミー id数字なし 記事1 記事2 記事3 HTML doc = Nokogiri::HTML.parse(html) doc.css('div').each do |div| unless div.attributes.key?('id') && div.attributes['id'].value =~ /\Apost-([0-9]+)\z/ next end puts div.css('h2').text end ``` これを実行すると、このように出力されます。 ``` 記事1 記事2 記事3 ``` このようにスクレイピングはパズルのように考えて工夫する事が必要です。