RubyのHTMLパーサーで複数のタグを抽出したい
現在、Rubyを用いて
あるWebページから特定のタグの要素を抽出して
テキストデータに出力したいと思い、プログラムを書いているのですが、
途中で行き詰ってしまいました。
ちなみにHpricotやNokogiriといったHTMLパーサーを試してみました。
パーサーを使うのは初めてです。
例えば以下のようにHTML文書に抽出したい部分がDIVタグとPタグに囲まれていた場合、
=====================================
・・・
<div class="content">
<div class="header">不要部分</div>
<div class="title">抽出したい文字列1</div>
<div class="subtitle">抽出したい文字列2</div>
<div class="subtitle">抽出したい文字列3</div>
<p class="paragraph">抽出したい文字列4</p>
<p class="paragraph">抽出したい文字列5</p>
<div class="comment">抽出したい文字列6</div>
<div class="footer">不要部分</div>
</div>
・・・
=====================================
このHTMLからまずは
抽出したい文字列1
抽出したい文字列2
抽出したい文字列3
抽出したい文字列4
抽出したい文字列5
抽出したい文字列6
といった出力が得たいのです。
プログラムも書いてみました。
=====================================
#ドキュメント全体を取得(dataにはHTMLの文字列が入っている)
html = Hpricot(data)
#内容部分(contentクラスのdiv)を取得(CSSセレクタで記述)
content = html/"div.content"
=====================================
ここまでは良いのですが、
そのあと、div要素を取り出すだけであれば
headerクラスと、footerクラスを抽出しないように
=====================================
(content/"div:not(.header):not(.footer)").each{ |line|
puts line.inner_html
}
=====================================
とすることで、
抽出したい文字列1
抽出したい文字列2
抽出したい文字列3
抽出したい文字列6
が得られますが、pタグをカンマでdivの前に追加して
=====================================
(content/"p,div:not(.header):not(.footer)").each{ |line|
puts line.inner_html
}
=====================================
のようにすると、
抽出したい文字列4
抽出したい文字列5
抽出したい文字列1
抽出したい文字列2
抽出したい文字列3
抽出したい文字列6
のように出力されます。
同様にdivの後にpを追加し
=====================================
(content/"div:not(.header):not(.footer),p").each{ |line|
puts line.inner_text
}
=====================================
のようにすると
抽出したい文字列1
抽出したい文字列2
抽出したい文字列3
抽出したい文字列6
抽出したい文字列4
抽出したい文字列5
のようになってしまいます。
つまり、複数のタグを指定すると、指定した順序で抽出されるようです。
代わりに子供すべてを列挙するchildのようなものがあるかと、調べてみたのですが、
どうやらそのような書き方はないようです。
複数のタグを含む場合にはHTMLパーサーでは解析できないのでしょうか。
パーサーは抽出時に順番を保証はしてくれないのでしょうか。
あきらめて、正規表現で抽出しようと思いましたが、
=====================================
<div class="comment">
<div class="comment_header">ごちゃごちゃ</div>
<div class="comment_body">抽出したい要素6</div>
</div>
=====================================
などDIVが入れ子となっている場合に、
非常にややこしく感じたので
お手上げ状態です。
どのように、解決できるでしょうか。
よろしくお願いします。