【问题标题】:How do I use Nokogiri to parse row by row using CSS selectors?如何使用 Nokogiri 使用 CSS 选择器逐行解析?
【发布时间】:2013-08-04 20:24:04
【问题描述】:

我有一个要解析的 HTML 表格。我想向下移动每个<TR> 并提取href。 HTML 如下所示:

table id="classified_table" class="vs-classified-table widget-off top" cellspacing="0" cellpadding="0" border="0">
    <tbody>
    <tr>
    <td id="classified_cell">
    <table class="vs-classified-table widget-off" cellspacing="0" cellpadding="0" border="0">
    <tbody>
    <tr id="vs_classified_73634384" class="classified row1 kiwii-clad-row kiwii-clad-featured">
    <tr id="vs_classified_74530668" class="classified row2 kiwii-clad-row kiwii-clad-featured">
    <tr id="vs_classified_62296263" class="classified row3 kiwii-clad-row kiwii-clad-featured">
    <tr id="vs_classified_62468547" class="classified row4 kiwii-clad-row kiwii-clad-featured">
    <tr id="vs_classified_47122034" class="classified row5 kiwii-clad-row kiwii-clad-featured">
    <tr id="vs_classified_78210646" class="classified row6 kiwii-clad-row">
    <tr id="vs_classified_78207083" class="classified row7 kiwii-clad-row">
    <tr id="vs_classified_69104369" class="classified row8 kiwii-clad-row">
    <tr id="vs_classified_78113204" class="classified row9 kiwii-clad-row">
    <tr id="vs_classified_52761813" class="classified row10 kiwii-clad-row">
    <tr id="vs_classified_78121746" class="classified row11 kiwii-clad-row">
    <tr id="vs_classified_76515548" class="classified row12 kiwii-clad-row">
    <tr id="vs_advert_middle" class="vs-advertisement advertisment-middle-2 vs-adsense-middle-BR-" style="border:none">
    <tr id="vs_classified_34048811" class="classified row13 kiwii-clad-row">

我的 Ruby 代码如下所示:

require 'rubygems'
require 'nokogiri'
require 'open-uri'

page = Nokogiri::HTML(open('http://servico-informatica.vivanuncios.com/computador+rio-de-janeiro-capital/'))
rows = page.css('tr#vs_classified_73634384.classified td.summary div a#vs-detail-link-1.kiwii-clear-none')
puts rows.text
#this works

rows [1..10].each do |row|
    puts "this isn't working :("

end

第一次打印成功打印了第一个&lt;TR&gt;的文本,但是each循环内的puts不起作用。

我要抓取的页面是:http://servico-informatica.vivanuncios.com/computador+rio-de-janeiro-capital/

【问题讨论】:

  • 您能否发布一个示例,说明您在输出方面正在寻找什么?就像你想要一个只有链接的数组?你想要链接中的文字吗?等等。
  • 您的 HTML 示例无效且缺少 HREF,并且您尚未在链接中指定您感兴趣的 HREF。

标签: html ruby parsing nokogiri mechanize


【解决方案1】:

您只收到一个结果,因为您的 css 查询正在使用 #,这意味着它正在页面上寻找一个唯一元素 (Spec)。

因此您需要修改查询以根据 css 类查找 href。

tr.classified td.summary a.classified-link

更新

上面的 css 路径会抓取所有的链接,然后你只需要遍历数组并使用 href 和 text 做你需要做的事情。

require 'rubygems'
require 'nokogiri'
require 'open-uri'

page = Nokogiri::HTML(open('http://servico-informatica.vivanuncios.com/computador+rio-de-janeiro-capital/'))
links = page.css("tr.classified td.summary a.classified-link")

links.map do |link|
  puts link['href']
  puts link.content
end

【讨论】:

  • 实际上,nokogiri 并不关心规范。如果有 2 个元素具有相同的 id,css 将返回两者。
  • 很公平,它仍然只抓取一个元素,因为页面正在创建唯一的 id
  • 那么最好的方法是什么?指向tbody,然后创建另一个指向TR的变量,然后循环?
  • 我想浏览每个 TR 并删除文本和链接。指向 Nokogiri 的最佳方式是什么?在Tbody?你能告诉我怎么做吗?
【解决方案2】:

我不知道您希望这样做:

rows [1..10].each do |row|
  puts "this isn't working :("
end

但我很确定它不会做你期望它做的事情。这实际上是这样解释的:

rows[1..10].each { ... }

并且由于rows(即Nokogiri::XML::NodeSet)只有一个条目,因此尝试从1 开始的extract a subset 会给您一个空的NodeSet;这意味着您实际上只是在说:

some_empty_node_set.each { ... }

这并没有什么用处。但是,如果您查看rows 中的第一个条目,您会发现您正在寻找的href

rows[0]['href']
# "http://servico-informatica.vivanuncios.com/..."

您还可以查看rows.attr('href')rows.first['href'],具体取决于您的口味和适合您的需求。

【讨论】:

  • “puts this is not working”只是为了确保我的代码在此之前一直正常工作。你对我想要做什么的猜测并不遥远:) 我试图获取每个条目的文本和 href () 你能告诉我用 CSS 路径选择什么吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
相关资源
最近更新 更多