作爲一個快速和骯髒的第一遍我會怎麼做:
html = <<EOT
<div id="__DailyStat__">
<table>
<tr class="blh"><th colspan="3">Today</th><th class="r" colspan="3">Yesterday</th></tr>
<tr class="blh"><th>Qnty</th><th>Size</th><th>Length</th><th class="r">Length</th><th class="r">Size</th><th class="r">Qnty</th></tr>
<tr class="blr">
<td>3</td>
<td>455</td>
<td>34</td>
<td class="r">3454</td>
<td class="r">5656</td>
<td class="r">3</td>
</tr>
<tr class="bla">
<td>1</td>
<td>1300</td>
<td>3664</td>
<td class="r">3545</td>
<td class="r">1000</td>
<td class="r">10</td>
</tr>
<tr class="blr">
<td>10</td>
<td>100000</td>
<td>3444</td>
<td class="r">3411</td>
<td class="r">36223</td>
<td class="r">15</td>
</tr>
</table>
</div>
EOT
# Today Yesterday
# Qnty Size Length Length Size Qnty
# 3 455 34 3454 5656 3
# 1 1300 3664 3545 1000 10
# 10 100000 3444 3411 36223 15
require 'nokogiri'
doc = Nokogiri::HTML(html)
使用CSS找到表格的開始,並定義一些地方以容納我們正在捕獲的數據:
table = doc.at('div#__DailyStat__ table')
today_data = []
yesterday_data = []
遍歷在表中的行,拒絕該標頭:
table.search('tr').each do |tr|
next if (tr['class'] == 'blh')
初始化陣列以從每個行捕捉相關數據,選擇性地將數據推入相應的數組:
today_td_data = [ 'Today' ]
yesterday_td_data = [ 'Yesterday' ]
tr.search('td').each do |td|
if (td['class'] == 'r')
yesterday_td_data << td.text.to_i
else
today_td_data << td.text.to_i
end
end
today_data << today_td_data
yesterday_data << yesterday_td_data
end
而輸出數據:
puts today_data.map{ |a| a.join(',') }
puts yesterday_data.map{ |a| a.join(',') }
> Today,3,455,34
> Today,1,1300,3664
> Today,10,100000,3444
> Yesterday,3454,5656,3
> Yesterday,3545,1000,10
> Yesterday,3411,36223,15
只是爲了幫助您可視發生了什麼事情,在出口處從「TR」循環中,陣列陣列的-3210個yesterday_data
陣列看起來像:
[["Today", 3, 455, 34], ["Today", 1, 1300, 3664], ["Today", 10, 100000, 3444]]
另一方面,不是循環在「TD」標籤和感應的標籤類,我可以抓住的「TR」的內容然後用scan
搶號和切片結果數組到「今天」和「昨天」陣列:
tr_data = tr.text.scan(/\d+/).map{ |i| i.to_i }
today_td_data = [ 'Today', *tr_data[0, 3] ]
yesterday_td_data = [ 'Yesterday', *tr_data[3, 3] ]
在現實世界中的發展,如在工作中,我第一次用這個來代替我因爲它很簡潔而寫了。
並注意到我沒有使用XPath。在Nokogiri中使用XPath並實現這一點非常實用,但爲了簡單起見,我更喜歡CSS訪問器。 XPath允許訪問單獨的「td」標籤內容,但它也開始看起來像線噪聲,這是我們在編寫代碼時要避免的,因爲它會影響維護。我也可以使用CSS深入到正確的「td」標籤,如'tr td.r'
,但我認爲它不會改進代碼,它只是一種替代方法。
謝謝@錫人。它工作正常,只是因爲得到一些錯誤,我必須將doc.at更改爲doc.css。我有一些小問題,我會盡力解決。我沒有足夠的聲望來投票,所以振作起來:) – JraNil 2011-06-04 20:28:21
'at'與CSS和XPath一起工作,但只返回節點的第一次出現,所以您可能有多個'table'標記。 'css'是'search'的別名,它返回一個NodeSet,AKA是一個節點數組,所以你必須索引結果或迭代它們。 'at_css'是與'at'等效的CSS。 – 2011-06-04 20:32:34
@JraNil此外,作爲參考,代碼與您的示例HTML一起工作,因此示例中必須缺少某些內容。如果您生成準確的樣本,我們可以提供更好的答案。 – 2011-06-04 20:39:48