使用 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
紧随 a 的同级元素的元素 DT
元素有一个 a
孩子。
笔记: :使用 //
强烈建议不要这样做,因为它通常会导致开发人员使用效率低下和异常。
只要 XML 文档的结构已知,就避免使用 //
缩写.
其他提示
你的问题不清楚你在寻找什么。
首先,HTML 格式错误,因为 <DT>
标签未正确关闭,且第一个字符存在非法字符 a
Ruby 1.9.2 不喜欢标签的文本,因为它不是 UTF-8。我在 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
}
在尝试修复之后,Nokogiri 中的 HTML 会解析为:
(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 两次,因为第一个将匹配 (换行)或空格。您可以在解析页面之前删除所有新行以避免重复调用。如果 DT 标记后有超过 1 个换行符,这也可能是一个好主意