你所需輸出是無稽之談:
['Raw name 1', 2,094, 0,017, 0,098, 0,113, 0,452]
# ~> -:1: Invalid octal digit
# ~> ['Raw name 1', 2,094, 0,017, 0,098, 0,113, 0,452]
我假設你想要引用的數字。
剝離,保持代碼的工作,並減少HTML更易於管理的例子,東西之後再運行它:
require 'nokogiri'
html = <<EOT
<table class="open">
<tr>
<th>Table name</th>
<th>Column name 1</th>
<th>Column name 2</th>
</tr>
<tr>
<th>Raw name 1</th>
<td>2,094</td>
<td>0,017</td>
</tr>
<tr>
<th>Raw name 5</th>
<td>2,094</td>
<td>0,017</td>
</tr>
</table>
EOT
doc = Nokogiri::HTML(html)
tables = doc.css('table.open')
tables_data = []
tables.each do |table|
title = table.css('tr[1] > th').text # !> assigned but unused variable - title
cell_data = table.css('tr > td').text
raw_name = table.css('tr > th').text
tables_data << [cell_data, raw_name]
end
導致:
tables_data
# => [["2,0940,0172,0940,017",
# "Table nameColumn name 1Column name 2Raw name 1Raw name 5"]]
的第一件事注意你是不是在使用title
,雖然你指定它。例如,當您清理代碼時可能發生這種情況。
css
,如search
和xpath
,返回一個NodeSet,類似於一個節點數組。當您在使用節點集或text
它inner_text
返回連接成一個字符串中每個節點的文本:
獲取包含的所有Node對象的內部文本。
這是它的行爲:
require 'nokogiri'
doc = Nokogiri::HTML('<html><body><p>foo</p><p>bar</p></body></html>')
doc.css('p').text # => "foobar"
相反,你應該遍歷找到的每個節點,並單獨提取其文本。這部分內容的很多倍SO:
doc.css('p').map{ |node| node.text } # => ["foo", "bar"]
這可以簡化爲:
doc.css('p').map(&:text) # => ["foo", "bar"]
見 「How to avoid joining all text from Nodes when scraping」 也。
文檔說這個約content
,text
和inner_text
一個節點時:
返回此節點的內容。
相反,你需要的單個節點的文本之後去:
require 'nokogiri'
html = <<EOT
<table class="open">
<tr>
<th>Table name</th>
<th>Column name 1</th>
<th>Column name 2</th>
<th>Column name 3</th>
<th>Column name 4</th>
<th>Column name 5</th>
</tr>
<tr>
<th>Raw name 1</th>
<td>2,094</td>
<td>0,017</td>
<td>0,098</td>
<td>0,113</td>
<td>0,452</td>
</tr>
<tr>
<th>Raw name 5</th>
<td>2,094</td>
<td>0,017</td>
<td>0,098</td>
<td>0,113</td>
<td>0,452</td>
</tr>
</table>
EOT
tables_data = []
doc = Nokogiri::HTML(html)
doc.css('table.open').each do |table|
# find all rows in the current table, then iterate over the second all the way to the final one...
table.css('tr')[1..-1].each do |tr|
# collect the cell data and raw names from the remaining rows' cells...
raw_name = tr.at('th').text
cell_data = tr.css('td').map(&:text)
# aggregate it...
tables_data += [raw_name, cell_data]
end
end
現在導致:
tables_data
# => ["Raw name 1",
# ["2,094", "0,017", "0,098", "0,113", "0,452"],
# "Raw name 5",
# ["2,094", "0,017", "0,098", "0,113", "0,452"]]
你能弄清楚如何要挾引用數爲小數接受到Ruby,或者你想要的操作內部數組。
請降低你的代碼需要說明問題的最低限度。在問題本身*中提供一個最小的HTML *示例,它也演示了這個問題。不要要求我們去頁面提取HTML或建立必要的周邊代碼來測試你的。閱讀「[問]」,「[mcve]」和http://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/ –
@錫人感謝。我更新了我的代碼。相信現在看起來好多了? – verrom
一般信息爲一般人尋找這個主題:http://ruby.bastardsbook.com/chapters/web-crawling/ – benjamin