2013-02-13 78 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')]

纠正我,如果事情是真的错了。