0

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} 

各行には5つのフィールドがあり、水平方向に実行して、5つのセルが入力されたら次の行に移動します。データはすべてそこにありますが、使用できません。

私は、CSVフォーマットコードを作成する方法を知っている誰かからコードを学習または取得したいと思っていました。

  1. スクリプトがコードを読み取っている間に、すべての新しいtd /tdx5を独自のセルに水平方向にダンプします。
  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,
4

1 に答える 1

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'satは何かの最初の出現を見つけて、ノードを返します。searchすべてのオカレンスを検索し、配列のように機能するNodeSetを返します。簡単にするために、XPathの代わりにCSSアクセサーを使用しています。


参考までに:

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

それはテストされていませんが、それは本当にとても簡単です。行って、それをいじってください。

于 2013-02-25T18:17:58.587 に答える