我有一些非常简单的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>
类型标签。最后可以跟着另一个span
或hr
。
我想以地址(“123 Main Street \ nSometown”),电话号码(“212-555-555”)和开放时间作为单独的字段结束。
有没有办法使用Nokogiri获取信息,或者使用正则表达式更容易做到这一点?
答案 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')]
如果出现问题,请纠正我。