我正在使用Ruby与Nokogiri一起抓取一个网站。
此脚本创建本地文本文件,打开URL,并在满足表达式tr td
时写入文件。它工作正常。
require 'rubygems'
require 'nokogiri'
require 'open-uri'
DOC_URL_FILE = "doc.csv"
url = "http://www.SuperSecretWebSite.com"
data = Nokogiri::HTML(open(url))
all_data = data.xpath('//tr/td').text
File.open(DOC_URL_FILE, 'w'){|file| file.write all_data}
每行有五个字段,我想水平运行,然后在填充五个单元格后转到下一行。数据全部存在,但不可用。
我希望从知道如何创建CSV格式代码的人那里学习或获取代码:
HTML的布局是:
<tr>
<td>John Smith</td>
<td>I live here 123</td>
<td>phone ###</td>
<td>Birthday</td>
<td>Other Data</td>
</tr>
最终产品应该是什么样子。
http://picpaste.com/pics/Screenshot-KRnqRGrP.1361813552.png
当前输出
john Smith I live here 123 phone ### Birthday Other Data,
答案 0 :(得分:5)
这是非常标准的代码,用于遍历表并将其单元格提取到数组数组中。您在此时对数据所做的工作取决于您,但将其传递给CSV非常容易。
require 'nokogiri'
require 'pp'
doc = Nokogiri::HTML(<<EOT)
<table>
<tr>
<td>John Smith</td>
<td>I live here 123</td>
<td>phone ###</td>
<td>Birthday</td>
<td>Other Data</td>
</tr>
<tr>
<td>John Smyth</td>
<td>I live here 456</td>
<td>phone ###</td>
<td>Birthday</td>
<td>Other Data</td>
</tr>
</table>
EOT
data = []
doc.at('table').search('tr').each do |tr|
data << tr.search('td').map(&:text)
end
pp data
哪个输出:
[["John Smith", "I live here 123", "phone ###", "Birthday", "Other Data"],
["John Smyth", "I live here 456", "phone ###", "Birthday", "Other Data"]]
代码使用at
找到第一个<table>
,然后使用<tr>
对每个search
进行迭代。对于每一行,它遍历单元格并提取其文本。
Nokogiri的at
找到第一次出现的东西,然后返回一个Node。 search
找到所有出现的并返回一个NodeSet,它就像一个数组。为简单起见,我使用的是CSS访问器,而不是XPath。
作为一个FYI:
File.open(DOC_URL_FILE, 'w'){|file| file.write all_data}
可以更简洁地写成:
File.write(DOC_URL_FILE, all_data)
我一直在研究这个问题。你能给我更多帮助吗?
唉...
您是否阅读过CSV文档,尤其是示例?如果我们用以下内容定义data = []
,我们会发生什么:
CSV.open("path/to/file.csv", "wb") do |data|
并用CSV块包装循环,如:
CSV.open("path/to/file.csv", "wb") do |data|
doc.at('table').search('tr').each do |tr|
data << tr.search('td').map(&:text)
end
end
这没有经过测试,但实际上非常简单。去吧,摆弄它。