2

我想解析一个包含从 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-tag 中,一些链接在 DD-tag 中有注释。

我执行以下操作来获取链接信息:

doc.xpath('//dt//a').each do |node|
  title = node.text
  url = node['href']
  tags = node['tags']
  puts "#{title}, #{url}, #{tags}"
end

我的问题是当存在 dd 标签时如何获取链接信息和评论?

4

3 回答 3

3

我的问题是当存在 dd 标签时如何获取链接信息和评论?

使用

//DT/a | //DT[a]/following-sibling::*[1][self::DD]

这将选择所有a具有DT父元素的元素以及作为具有子元素的元素DD的紧随其后的兄弟元素的所有元素。DTa

注意//强烈建议不要使用 ,因为它通常会导致开发人员使用它时效率低下和异常。

只要已知 XML 文档的结构,就避免使用//缩写.

于 2010-12-18T17:53:26.387 回答
2

您的问题不清楚您在寻找什么。

首先,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 &sect; 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

这意味着, find<dt>后跟<dd>. 您不能/不能查找dt后跟add因为这不是 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
于 2010-12-18T09:26:17.160 回答
0

我假设:

<DD>Window shopping from Amazon

有一个结束 /DD 标记,我无法从您的页面片段中分辨出来。如果是这样,你可以这样做:

comment = node.parent.next_sibling.next_sibling.text rescue nil

您需要调用 next_sibling 两次,因为第一个将匹配 \n (新行)或空格。您可以在解析页面之前删除所有新行以避免双重调用。如果 DT 标记后有超过 1 个换行符,这也可能是个好主意

于 2010-12-18T09:41:36.663 回答