使用Nokogiri定位没有标签的文本

时间:2013-02-13 16:34:10

标签: ruby regex nokogiri text-parsing

我有一些非常简单的HTML,我正在尝试使用Nokogiri解析(在Ruby上):

<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获取信息,或者使用正则表达式更容易做到这一点?

2 个答案:

答案 0 :(得分:4)

使用Nokogiri and XPath你可以这样做:

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"
# }

使用正确的解析器比使用正则表达式(a well documented bad ideaTM更容易,更健壮。)

答案 1 :(得分: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"

第一个以第二个跨度开始,然后选择之前的文本() 你可以尝试另一种方法 - 从第一个跨度开始,选择文本(),最后用谓词检查下一个跨度。

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')]

如果出现问题,请纠正我。