从Nokogiri::XML::NodeSet中解析Ruby <a>链接信息

3

我从页面中提取了一个Nokogiri::XML::NodeSet,以下是结果:

<a href="http://www.goldsteinpatentlaw.com" target="_blank" title="Goldstein Patent Law ( U.S.A. )">
    <img src="http://www.asdf.com/LBM_Images/Offices//law-firm-goldstein-patent-law-photo-1258381.jpg" height="62" width="100" alt="Goldstein Patent Law (U.S.A.)">
</a>

我不知道如何将(对人类来说很明显的)<a>标签转换为Mechanize/Nokogiri解析对象,以便我可以轻松地从链接中检索信息。
Nokogiri/Mechanize文档非常令人困惑,因为我从不知道该看哪个。不确定哪个先出现,哪个使用哪个等等。对于我正在尝试的简单抓取和解析来说,似乎过于复杂了。

2
Nokogiri只是一个XML/HTML解析器。Mechanize是一个HTTP用户代理,用于与Web服务器交互。你的问题是什么?你想解析那段文本吗?如果它是一个NodeSet,它已经被解析了。 - tadman
2
"Nokogiri/Mechanize文档非常令人困惑,因为我从不知道该看哪个。Mechanize是一种完全不同的工具,它恰好在内部使用Nokogiri,因此不要查看Mechanize以获取任何Nokogiri信息。Nokogiri是一个解析器,因此请查看Nokogiri :: XML :: Node... NodeSet文档,了解您需要了解的大部分内容。从那里,您可以四处探索并学习它还能做什么。" - the Tin Man
3个回答

2
一个NodeSet就像一个数组。如果你在NodeSet上使用puts(),那么就像在数组上使用puts一样,Ruby会在每个单独的行上输出NodeSet中每个项目的字符串表示形式。NodeSets可以包含各种对象,但通常它们将包含称为<Nokogiri::XML::Element>的对象,这些对象代表您的html中的标记。
从你的输出中可以看出,你的NodeSet只有一个项目,你所看到的是该项目的字符串表示形式。以下是一个例子:
require 'nokogiri'

str = "<div>hello</div><div>world</div>"
html_doc = Nokogiri::HTML(str)

divs = html_doc.xpath("//div")

divs.each do |div|
  p div
end

puts '*' * 10
puts divs


    --output:--
#<Nokogiri::XML::Element:0x80836ec4 name="div" children=[#<Nokogiri::XML::Text:0x80836a00 "hello">]>
#<Nokogiri::XML::Element:0x80836668 name="div" children=[#<Nokogiri::XML::Text:0x80836064 "world">]>
**********
<div>hello</div>
<div>world</div>

所以,您只需要检索NodeSet的第一个元素,就像您检索数组中的第一个元素一样:

p divs[0]

或者,如果你知道你的节点集中只有一个元素,那么你可以使用:

div = html_doc.at_xpath("//div")

它不返回节点集,而是返回与xpath匹配的第一个元素。

当你真正想知道你得到了什么时,应该使用p而不是puts


如果您知道NodeSet中只会有一个元素,或者您只想要第一个匹配的元素,那么请注意。 - the Tin Man
1
@the Tin Man,我的回答已经包含了这个信息:使用which代替返回NodeSet的方法,只返回匹配xpath的第一个元素。 - 7stud

1
这是您在寻找的内容吗?
require 'nokogiri'
str = '<a href="http://www.goldsteinpatentlaw.com" target="_blank" title="Goldstein Patent Law ( U.S.A. )">
          <img src="http://www.asdf.com/LBM_Images/Offices//law-firm-goldstein-patent-law-photo-1258381.jpg" height="62" width="100" alt="Goldstein Patent Law (U.S.A.)">
       </a>'
doc = Nokogiri::HTML(str)
link = doc.at('a')
#=> #<Nokogiri::XML::Element:0x1744488 name="a" attributes=[
     #<Nokogiri::XML::Attr:0x174444c name="href" value="http://www.goldsteinpatentlaw.com">, 
     #<Nokogiri::XML::Attr:0x1744440 name="target" value="_blank">,
     #<Nokogiri::XML::Attr:0x1744434 name="title" value="Goldstein Patent Law ( U.S.A. )">] children=[#<Nokogiri::XML::Text:0x1743d20 "\n    ">, 
     #<Nokogiri::XML::Element:0x1743c9c name="img" attributes=[#<Nokogiri::XML::Attr:0x1743c60 name="src" value="http://www.asdf.com/LBM_Images/Offices//law-firm-goldstein-patent-law-photo-1258381.jpg">, 
     #<Nokogiri::XML::Attr:0x1743c54 name="height" value="62">, #<Nokogiri::XML::Attr:0x1743c48 name="width" value="100">, 
     #<Nokogiri::XML::Attr:0x1743c3c name="alt" value="Goldstein Patent Law (U.S.A.)">]>,
     #<Nokogiri::XML::Text:0x17433d8 "\n">]>

你可以使用atat_cssat_xpath选择器来获取你想要的内容,然后进行相应的操作。
link.attributes["href"].value
#=> "http://www.goldsteinpatentlaw.com"
link.attributes["title"].value
#=> "Goldstein Patent Law ( U.S.A. )"

这正是我在寻找的。我以前做过类似的事情,但忘记了如何做。再次感谢! - Kyle Carlson
1
你可以使用 CSS 或 XPath 选择器来获取你想要的内容,但是...嗯,有些不同。CSSXPath 就像 search 一样,返回一个类似于数组的 NodeSet。而 atat_xpathat_css 则返回一个节点。虽然这些方法看起来相似,但是在 NodeSet 和 Node 中使用它们会得到非常不同的结果。 - the Tin Man
@theTinMan你是正确的,为了帮助楼主,我过于简化了问题,但我已经相应地更新了我的答案。 - engineersmnky
at、at_xpath 和 at_css 返回一个节点。嗯,有点像。它们返回的节点类似于构造函数 {} 返回 BasicObject。 - 7stud

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接