2012-05-22 69 views
0

頁面我試圖抓取一個CSV數據庫/ Ruby數組列出470個不規則大小組的總記錄,每個組前面有一個日期(共22個唯一日期)。基於先前斷開連接的HTML元素匹配DOM節點的子集

我不知道該怎麼做,因爲組未被組織到任何HTML表格中,也沒有任何「父」可能導致每個組的日期的DOM中的層次結構,只有乾淨的<div class="line">可見記錄div列表,偶爾在前面只有一個<span class="date">Thursday, May 24, 2012</span>保存僅適用於下一個X記錄的日期,直到打印新的日期。

irb它正確地顯示:

$page = $agent.get(pageurl) # gets page with Mechanize 
doc = $page.parser # returns Nokogiri::HTML 

(records = doc.search('html body div#wrapper div#innerwrapper div#content div.line')).size 
=> 470 
(dates = doc.search('html body div#wrapper div#innerwrapper div#content span.date')).size 
=> 22 

顯示例如第一次約會:

doc.search('html body div#wrapper div#innerwrapper div#content span.date')[0].text 
=> "Wednesday, May 23, 2012" 

我的目標是正確的日期作爲一個字段添加到每個470個記錄在保存到CSV文件之前,上面找到的doc.search。

Nokogiri(或Mechanize)可以根據它們在DOM中的位置幫助我檢索這些記錄,即緊接在dates[N].text之後但在下一個<span class="date">之前?

我可以迭代N從0到21,爲所有470記錄添加一個主數組/ CSV對象,但是對於每個組添加相應的date字段。

回答

1

首先,您可以簡化您的搜索。由於內容是id,並且它根據定義唯一標識特定的div,因此您不需要任何上述路徑信息。

records = doc.search('div#content div.line') 

每條記錄​​,你可以拉使用XPath的preceding-sibling軸的日期。總之:

doc.search('div#content div.line').each do |record| 
    date = record.xpath('preceding-sibling::span[@class="date"][1]').text 
    #append to CSV 
end 

中的XPath說:找到有一類「日期」([@class="date"])相同的水平(preceding-sibling::span)前面的跨度,並採取第一個這樣的一個([1]),以確保您獲得最近的日期跨度)。

+0

是的感謝!目前我正在使用確切的xpath,因爲它在日期上空白。尋找可能的叔叔/家長啤酒花等。也許我會發佈一個HTML的片段,如果我不知道。 – Marcos

+0

有趣的是,在早期版本中,我在我的示例html中將日期作爲「叔叔」節點。我用'../之前的兄弟:: span'來達到它。 ('..'表示父母) –

+0

在編輯之前給了我麻煩的版本。這對我有用:'records [0] .xpath('preceding-sibling :: span [@ class =「date」] [1]')。text'再次感謝! – Marcos

1

這是遍歷使用另一個好時機:

doc.traverse do |node| 
    @date = node.text if 'span' == node.name && 'date' == node[:class] 
    puts [@date, node.text].join(', ') if 'div' == node.name && 'line' == node[:class] 
end 
+0

同樣很棒!我看到那裏發生了什麼。這個'遍歷'將會很有用 - 讓我想起我正在瘋狂地準備處理像'sed'和'awk'這樣的原始文本處理器,而不是任何xml/xsltproc或nokogiri輔助工具。 – Marcos