我正在尝试抓取CSV数据库/Ruby数组的页面列出了470条大小不均匀的组的记录,每个组前面都有一个日期(总共22个唯一日期(。
我不确定该怎么做,因为组没有组织成任何 HTML 表,也没有 DOM 中的任何层次结构,其中"父"可能导致每个组的日期,只有<div class="line">
可见记录div 的干列表,偶尔前面只有一个<span class="date">Thursday, May 24, 2012</span>
保存仅适用于下一个 X 记录的日期,直到打印新日期。
在irb
中,它正确地显示:
$page = $agent.get(pageurl) # gets page with Mechanize
doc = $page.parser # returns Nokogiri::HTML
(records = doc.search('html body div#wrapper div#innerwrapper div#content div.line')).size
=> 470
(dates = doc.search('html body div#wrapper div#innerwrapper div#content span.date')).size
=> 22
显示第一个日期,例如:
doc.search('html body div#wrapper div#innerwrapper div#content span.date')[0].text
=> "Wednesday, May 23, 2012"
我的目标是在保存到 CSV 文件之前,将正确的日期作为字段附加到上面找到的 470 条记录 doc.search 中的每一条。
Nokogiri(或 Mechanize(能否帮助我根据它们在 DOM 中的位置(即紧随dates[N].text
之后但在下一个<span class="date">
之前(分组检索这些记录?
我可以迭代 N 从 0 到 21,附加到所有 470 条记录的主数组/CSV 对象,但对于每个组,添加适当的date
字段。
首先,您可以稍微简化搜索。由于内容是一个id
,并且根据定义,它唯一标识该特定div
,因此您不需要上述任何路径信息。
records = doc.search('div#content div.line')
从每条记录中,您可以使用 xpath 的preceding-sibling
轴拉取日期。完全:
doc.search('div#content div.line').each do |record|
date = record.xpath('preceding-sibling::span[@class="date"][1]').text
#append to CSV
end
XPath 说:在同一级别(preceding-sibling::span
(找到具有"日期"类([@class="date"]
(的前面的跨度,并取第一个这样的跨度([1]
(以确保你得到最近的日期跨度(。
这是使用遍历的另一个好时机:
doc.traverse do |node|
@date = node.text if 'span' == node.name && 'date' == node[:class]
puts [@date, node.text].join(', ') if 'div' == node.name && 'line' == node[:class]
end