【发布时间】:2015-11-03 13:55:52
【问题描述】:
我从atpworldtour.com 中抓取了排名表,并尝试访问玩家姓名。
表格中的一行示例如下所示:
<tr>
<td class="rank-cell">1</td>
<td class="move-cell">
<div class="move-none"></div>
<div class="move-text">
</div>
</td>
<td class="country-cell">
<div class="country-inner">
<div class="country-item">
<img src="/~/media/images/flags/srb.png" alt="SRB" onerror="this.remove()">
</div>
</div>
</td>
<td class="player-cell">
<a href="/en/players/novak-djokovic/d643/overview" data-ga-label="Novak Djokovic">Novak Djokovic</a>
</td>
<td class="age-cell">28</td>
<td class="points-cell">
<a href="/en/players/novak-djokovic/d643/rankings-breakdown?team=singles" data-ga-label="rankings-breakdown">15,785</a>
</td>
<td class="tourn-cell">
<a href="/en/players/novak-djokovic/d643/player-activity?matchType=singles" data-ga-label="player-activity">17</a>
</td>
<td class="pts-cell">1,500</td>
<td class="next-cell">0</td>
</tr>
我尝试了几种不同的方法来提取这些信息。到目前为止,我迄今为止取得的最大成功是:
url = "http://www.atpworldtour.com/en/rankings/singles"
doc = Nokogiri::HTML(open(url))
doc.css("tr").each do |row|
puts row.css("td a")
end
问题是,每一行中玩家名字后面还有两个链接,所以我把它们放在一起。玩家的名字是表格中的第四个单元格,所以我尝试先拉出第四个单元格,然后访问链接:
doc.css("tr").each do |row|
cell = row.css("td")[3]
puts cell.css("a").text
end
但这会返回错误undefined method 'css' for nil:NilClass。
经过进一步调查,cell 似乎存储了所有带有玩家姓名的单元格,而不仅仅是当前迭代 row 的单元格,但是当我尝试遍历 cell 时,我得到了相同的结果undefined method 错误。
我也尝试使用 XPath 解决这个问题:
doc.xpath("//tr").each do |row|
puts row.xpath("/td[3]/a").text
end
但输出是一大片空白区域,其中应列出名称。
- 关于我做错了什么有什么提示吗?
- 谁能告诉我有关在 Nokogiri 中使用 CSS/XPath 选择器的详细文档,我将不胜感激。
到目前为止,我发现的所有内容都只涵盖了最基本的内容,而且我很难找到有关如何执行更复杂操作的信息。
我实际上是使用:
doc.xpath("//tr").each do |row|
puts row.at_css("a").text
end
但是任何帮助找到适当的文档/教程以在 Nokogiri 中使用 XPath 和 CSS 选择器仍然很棒。
【问题讨论】:
-
doc.css('.player-cell a').map(&:text)呢? -
是的,这也很有效,而且更好,谢谢。如果您可以将其与解释一起放在答案中,我将很高兴接受它:)
-
向我们询问教程链接的问题是题外话。这是您研究答案的一部分。 Stack Overflow 中包含显示和使用 CSS/XPath 和 Nokogiri 的完整答案,因此请在此处搜索并阅读 Nokogiri 节点文档。复杂搜索是使用简单搜索构建的;复杂的选择器掩盖了问题,所以从小的搜索开始,慢慢地聚合和测试,看看你是否仍然可以达到你需要的东西。