2013-02-13 87 views
3

標籤的目標文本我有我嘗試使用引入nokogiri(關於Ruby)來分析一些非常裸露的HTML:不使用引入nokogiri

<span>Address</span><br /> 
123 Main Street<br /> 
Sometown<br /> 
<span>Telephone</span><br /> 
<a href="tel:212-555-555">212-555-555</a><br /> 

    <span>Hours</span><br /> 
    M-F: 8:00-21:00<br /> 
     Sat-Sun: 8:00-21:00<br /> 
<hr /> 

我唯一的標記是頁面內容周圍<div>。我想要的每件東西都有一個<span>Address</span>類型標籤。最後可以跟着另一個spanhr

我想結束地址(「123 Main Street \ nSometown」),電話號碼(「212-555-555」)和開放時間作爲單獨的字段。

有沒有一種方法可以使用Nokogiri獲取信息,或者使用正則表達式執行此操作會更容易嗎?

+0

用'(?= )'分隔上面的文字?然後清潔標籤? – nhahtdh 2013-02-13 16:37:04

+2

使用Nokogiri。總是,總是_always_使用正則表達式的解析器來處理HTML/XML,除非你喜歡痛苦。 – iain 2013-02-13 18:03:05

+1

你可以發佈你想要的輸出嗎? – 2013-02-13 18:24:52

回答

4

使用Nokogiri and XPath你可以做這樣的事情:(這是a well documented bad ideaTM

def extract_span_data(html) 
    doc = Nokogiri::HTML(html) 
    doc.xpath("//span").reduce({}) do |memo, span| 
    text = '' 
    node = span.next_sibling 
    while node && (node.name != 'span') 
     text += node.text 
     node = node.next_sibling 
    end 
    memo[span.text] = text.strip 
    memo 
    end 
end 

extract_span_data(html_string) 
# { 
# "Address" => "123 Main Street\nSometown", 
# "Telephone" => "212-555-555", 
# "Hours"  => "M-F: 8:00-21:00\n  Sat-Sun: 8:00-21:00" 
# } 

使用合適解析器比使用正則表達式更容易和更強大的

+0

感謝您的回答。所以如果我明白了,Nokogiri會將以'
'分開的東西當作單獨的節點來處理?並且只有'memo'的行將條目添加到'reduce({})'中給出的哈希中? – 2013-02-13 22:05:54

+0

是的,在XML/HTML中,「節點」是標籤及其內容或文本塊。所以'「一個
b」'是三個節點,文本:「a」,元素:'
',文本:「b」。 – maerics 2013-02-13 22:09:40

0

我想(而不是學習)關於xpath:

d.xpath("span[2]/preceding-sibling::text()").each {|i| puts i} 
# 123 Main Street 
# Sometown 

d.xpath("a/text()").text 
# "212-555-555" 

d.xpath("span[3]/following::text()").text.strip 
# "M-F: 8:00-21:00  Sat-Sun: 8:00-21:00" 

第一個以第二個span開頭,並選擇之前的text()。
您可以在這裏嘗試另一種方法 - 從第一個跨度開始,選擇text()並結束用於檢查下一個跨度的謂詞。

d.xpath("span[1]/following::text()[following-sibling::span]").each {|i| puts i} 
# 123 Main Street 
# Sometown 

如果文檔有更多的跨度,您可以用正確的人開始:
span[x]可以通過span[contains(.,'text-in-span')]
span[3] ==被取代span[contains(.,'Hours')]

糾正我,如果事情是真的錯了。