我在Ruby中使用Nokogiri gem并遇到了一些问题。
我想从网页上抓取地址,并且地址的显示方式没有固定格式。
我有一个邮政编码列表,我希望我的Ruby脚本返回包含邮政编码的节点,以便找到地址的其余部分。
这是我在Ruby中的一些示例HTML内容:
require 'nokogiri'
require 'open-uri'
content1 = '
<div>
<div>
<div>Our Address:</div>
1 North Street
North Town
North County
N21 4DD
</div>
</div>'
doc = Nokogiri::HTML(content1)
result = doc.search "[text()*='N21 4DD']"
puts result.inspect
这会返回[]
我理解上面的示例是一种以HTML格式显示地址的奇怪方式,但这是我能够展示我遇到的问题的最简单方法。这是另一个不返回任何内容的content
变量:
content1 = '
<div>
<div>Our Address:</div>
<div>
1 North Street<br>
North Town<br>
North County<br>
N21 4DD
</div>
</div>'
我知道Nokogiri可能会遇到上述问题,因为<br>
代码应为</br>
,但这在网站上很常见。
此示例有效:
content1 = '
<div>
<div>Our Address:</div>
<div>
1 North Street
North Town
North County
N21 4DD
</div>
</div>'
有人可以解释为什么在上面的前两个content
示例中找不到节点,以及如何解决这个问题?
我没有在上面的示例content
示例中找到可以找到邮政编码的自定义解决方案 - 这些仅用于演示目的。邮政编码(和地址)可以是html中的任意位置 - body
,p
,div
,td
,span
,li
等。
感谢。
答案 0 :(得分:0)
使用Xpath:
doc.xpath('.//div[contains(.,"N21 4DD")]')
这仍然会返回两个节点,因为有一个嵌套的div。我不确定是否有办法让中间div没有'Our Address'div,因为它位于同一节点。
答案 1 :(得分:0)
让我们看一下第一个以及Nokogiri如何翻译你的“css”(这不是有效的css btw):
Nokogiri::CSS.xpath_for "[text()*='N21 4DD']"
#=> ["//*[contains(child::text(), 'N21 4DD')]"]
好的,所以这里的问题是child :: text()实际上只匹配第一个文本节点,即“我们的地址”div之前的空文本。
doc.search("//*[contains(child::text(), 'N21 4DD')]").length
#=> 0
没有匹配=不好。
现在让我们使用:contains
伪:
Nokogiri::CSS.xpath_for ":contains('N21 4DD')"
#=> ["//*[contains(., 'N21 4DD')]"]
doc.search("//*[contains(., 'N21 4DD')]").length
#=> 4
这实际上是正确的,但可能不是你所期望的。
让我们再尝试一下:
doc.search("//*[text()[contains(., 'N21 4DD')]]").length
#=> 1
听起来这就是你要找的东西。只是在子文本节点中包含字符串的div。