0

我正在为 yahoo.finance.com 网站制作一个小型刮板。当我提出这个要求时:

symbol = 'AAPL'

@page = Nokogiri::HTML(open("http://finance.yahoo.com/q?s=#{symbol.upcase}&ql=1"))

def marketCap(symbol)
  @page.xpath("//*[(@id = \"yfs_j10_#{symbol.downcase}\")]").text
end

puts marketCap(symbol)

它打印两次相同的结果。

“495.74B495.74B”

我查看了源代码,标签只显示一次

<span id="yfs_j10_f">51.74B</span>

如果我使用 css 选择器,我会遇到同样的问题。

这是一个错误还是我犯了一个错误?

谢谢。

4

2 回答 2

1
@page.xpath("//*[(@id = \"yfs_j10_#{symbol.downcase}\")]").text

不正确。

xpath返回一个 NodeSet,它类似于一个 Array。如果它包含两个元素text将同时包含它们:

@page.xpath("//*[(@id = \"yfs_j10_#{symbol.downcase}\")]").size
=>2

相反,使用at_xpath来查找第一个。

@page.at_xpath("//*[(@id = \"yfs_j10_#{symbol.downcase}\")]").text
=> "495.74B"

现在,我建议不要使用 XPath,我觉得它通常更复杂且可读性更差,我建议您使用 CSS 作为访问器:

@page.at("#yfs_j10_#{symbol.downcase}").text
=> "495.74B"

请注意,我使用at了代替at_cssor at_xpathat感知您传递的是 XPath 还是 CSS。它是通用的,在确定使用哪个时可能会出错,但它也更容易使用。search代替cssor也是如此xpath。它像其他两个一样返回一个 NodeSet,但会感知它应该使用哪种类型的访问器。

于 2013-01-06T21:46:01.963 回答
0

解决了这个问题。看起来它与另一个选择器冲突。

这解决了问题

def marketCap(symbol)
  @page.css("#yfi_comparison #yfs_j10_#{symbol.downcase}").text
end
于 2013-01-06T21:51:37.127 回答