【问题标题】:Formatting HTML into CSV将 HTML 格式化为 CSV
【发布时间】:2013-02-10 21:42:26
【问题描述】:

我正在使用 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 格式代码的人那里学习或获取代码:

  1. 在脚本读取代码时,将每个新的 td /td x5 水平转储到自己的单元格中。
  2. 转到下一行,等等。

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,

【问题讨论】:

  • “不可用”是什么意思?你能分享一下你当前的输出是什么样的吗?此外,将您的目标显示为文本文件会有所帮助(它在 Excel 中的外观并没有多大帮助)。此外,如果该网站不是您的网站,请注意此类工作,根据您的法律,可能会被禁止(至少用于商业用途)。
  • 本网站提供的信息对公众开放。这五个字段是任意的,与我放下的内容没有任何关系。例如,我使用数字/文本的字段的用途和动态。

标签: ruby csv nokogiri


【解决方案1】:

这是遍历表格并将其单元格提取到数组数组中的非常标准的代码。此时您如何处理数据取决于您,但将其传递给 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 定位第一个&lt;table&gt;,然后使用search 遍历每个&lt;tr&gt;。对于每一行,它会遍历单元格并提取它们的文本。

Nokogiri 的at 找到第一次出现的东西,并返回一个节点。 search 查找所有匹配项并返回一个 NodeSet,它的作用类似于一个数组。为简单起见,我使用 CSS 访问器,而不是 XPath。


仅供参考:

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

这没有经过测试,但它真的很简单。去摆弄它。

【讨论】:

  • 工作完美!但它只在终端中发布格式,而不是输出文件。将其导出到文本文件或 CSV 文件的正确方法是什么?当我将其转储到文本文件或 csv 中时,我没有得到格式。例如:“File.open(DOC_URL_FILE, 'w'){|file| file.write data}”这给了我“john Smith I live here 123 phone ### Birthday Other Data”,
  • 我不会为你写一个完整的解决方案。阅读CSV documentation,它很好地说明了它。您只需要弄清楚如何以及在何处正确打开 CSV 文件并更改我的代码中的变量。顺便说一句,您的示例输出不是 CSV,它是伪列,根本无法加载数据。
  • 感谢您的链接。我会再读一遍。网上还有其他资料可以帮到我吗?
  • 我一直在研究这个问题。你能给我更多的帮助吗?我觉得我快要让它正确格式化了。
猜你喜欢
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 2016-07-27
  • 1970-01-01
  • 2011-07-26
  • 2011-02-07
相关资源
最近更新 更多