我正在为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.74 b495.74b "
我看了源代码,标签只显示了一次
<span id="yfs_j10_f">51.74B</span>
如果我使用css选择器,我会遇到同样的问题。
这是一个bug还是我犯了一个错误?
谢谢。
@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(我觉得XPath通常更复杂,可读性更差),而是建议使用CSS作为访问器:
@page.at("#yfs_j10_#{symbol.downcase}").text
=> "495.74B"
注意,我使用at
而不是at_css
或at_xpath
。at
检测您传递的是XPath还是CSS。它是通用的,可能会犯错误,不知道该使用哪个,但它也更容易使用。search
也是如此,而不是css
或xpath
。它像其他两个一样返回一个NodeSet,但是它感知应该使用哪种类型的访问器。
问题解决了。它似乎与另一个选择器冲突了。
这个问题解决了
def marketCap(symbol)
@page.css("#yfi_comparison #yfs_j10_#{symbol.downcase}").text
end