Nokogiri を使用して Delicious.com からエクスポートされたリンクを含むファイルを解析する最良の方法は?
-
11-10-2019 - |
質問
Delicious からエクスポートされたリンクを含む HTML ファイルを解析したいと考えています。解析には Nokogiri を使用しています。ファイルの構造は次のとおりです。
<DT>
<A HREF="http://mezzoblue.com/archives/2009/01/27/sprite_optim/"
ADD_DATE="1233132422"
PRIVATE="0"
TAGS="irw_20">mezzoblue § Sprite Optimization</A>
<DT>
<A HREF="http://datamining.typepad.com/data_mining/2008/11/minority-report-interface.html"
ADD_DATE="1226827542"
PRIVATE="0"
TAGS="irw_20">Minority Report Interface</A>
<DT>
<A HREF="http://www.windowshop.com/"
ADD_DATE="1225267658"
PRIVATE="0"
TAGS="irw_20">Amazon Windowshop Beta</A>
<DD>Window shopping from Amazon
ご覧のとおり、リンク情報は DT タグ内にあり、一部のリンクには DD タグ内にコメントが含まれています。
リンク情報を取得するには次の操作を行います。
doc.xpath('//dt//a').each do |node|
title = node.text
url = node['href']
tags = node['tags']
puts "#{title}, #{url}, #{tags}"
end
私の質問は、dd タグが存在する場合、リンク情報とコメントをどのように取得するかです。
解決
私の質問は、DDタグが存在するときにリンク情報とコメントを取得するにはどうすればよいですか?
使用:
//DT/a | //DT[a]/following-sibling::*[1][self::DD]
これですべてが選択されます a
を持つ要素 DT
親もみんなも DD
の直後の兄弟要素である要素 DT
を持つ要素 a
子供。
注記:の使用 //
通常、開発者にとって使用すると非効率性や異常が発生するため、使用しないことを強くお勧めします。
XML ドキュメントの構造がわかっている場合は、常に、 //
略語.
他のヒント
あなたの質問では、何を探しているのかが明確ではありません。
まず、HTML の形式が不正です。 <DT>
タグが正しく閉じられておらず、最初のタグに不正な文字があります。 a
タグのテキストは UTF-8 ではないため、Ruby 1.9.2 では好まれません。TextMate で文字をエンティティに変換しました。
html = %{
<DT>
<A HREF="http://mezzoblue.com/archives/2009/01/27/sprite_optim/" ADD_DATE="1233132422" PRIVATE="0" TAGS="irw_20">mezzoblue § Sprite Optimization</A>
<DT>
<A HREF="http://datamining.typepad.com/data_mining/2008/11/minority-report-interface.html" ADD_DATE="1226827542" PRIVATE="0" TAGS="irw_20">Minority Report Interface</A>
<DT>
<A HREF="http://www.windowshop.com/" ADD_DATE="1225267658" PRIVATE="0" TAGS="irw_20">Amazon Windowshop Beta</A>
<DD>Window shopping from Amazon
}
その HTML は、修正を試行した後、Nokogiri で次のように解析されます。
(rdb:1) print doc.to_html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<dt>
<a href="http://mezzoblue.com/archives/2009/01/27/sprite_optim/" add_date="1233132422" private="0" tags="irw_20">mezzoblue § Sprite Optimization</a>
<dt>
<a href="http://datamining.typepad.com/data_mining/2008/11/minority-report-interface.html" add_date="1226827542" private="0" tags="irw_20">Minority Report Interface</a>
<dt>
<a href="http://www.windowshop.com/" add_date="1225267658" private="0" tags="irw_20">Amazon Windowshop Beta</a>
</dt>
</dt>
</dt>
<dd>Window shopping from Amazon
</dd>
</body></html>
終了方法に注目してください dt
タグは唯一の直前にグループ化されます dd
鬼ごっこ?面倒ですが、問題はありません。検索方法は変わらないからです。 dd
コンテンツ。
doc = Nokogiri::HTML(html, nil, 'UTF-8')
comments = []
doc.css('dt + dd').each do |a|
comments << a.text
end
puts comments
# >> Window shopping from Amazon
つまり、見つけてください <dt>
に続く <dd>
. 。探さない/探せない dt
に続く a
に続く dd
それは HTML が解析する方法ではないからです。本当にそうでしょう dt
に続く dd
, 、それは何ですか?dt + dd
" 手段。
あなたの質問からは、次のような内容を探しているように見えます。 a
タグ:
comments = []
doc.css('a').each do |a|
comments << a.text
end
puts comments
# >> mezzoblue § Sprite Optimization
# >> Minority Report Interface
# >> Amazon Windowshop Beta
私は次のことを想定しています:
<DD>Window shopping from Amazon
/DD 終了タグがありますが、ページのスニペットだけではわかりません。その場合は、次のようにすることができます。
comment = node.parent.next_sibling.next_sibling.text rescue nil
最初の呼び出しは (改行) または空白と一致するため、next_sibling を 2 回呼び出す必要があります。二重呼び出しを避けるために、ページを解析する前にすべての新しい行を削除できます。DT タグの後に複数の改行文字がある場合にも、これは良いアイデアかもしれません。