在Rails + Nokogiri中检索之间的文本

时间:2013-01-08 04:34:48

标签: ruby ruby-on-rails-3 nokogiri

对于以下部分HTML,我正在尝试检索文本“进行研究......找到治疗方法!”通过Nokogiri在两个<br>标签之间。

<b>Multiple Sclerosis National Research Institute</b><br>
<!-- <b>CFC Code: 12135</b><br />     ***** This is edited by Anas -->
<a href="http://www.ms-research.org" target="_blank">http://www.ms-research.org</a><br> 
(866)-676-7400<br> 
Conducts research towards understanding, treating and halting the progression of multiple sclerosis and related diseases. Current research progress is promising. Please help us find cures!<br>
<a href="/ntn/charities/view.aspx?record_id=510">Click here for more info</a><br><br>

到目前为止,我已经能够使用以下代码检索nameurl

url = "https://www.neighbortonation.org/ntn/charities/home.aspx"    
doc = Nokogiri::HTML(open(url))

doc.css("#site-pagecontent table table td").each do |item|
    name = item.at_css("b").text unless item.at_css("b").blank?
    url = item.at_css("a")[:href] unless item.at_css("a").blank?
end

但是我试图在特定的<br>标签之间检索文本时遇到困难。我通过Extracting between <br> tags with Nokogiri?尝试了这些建议,但这似乎不起作用。有任何想法吗?我应该使用xpath,search还是regex?

2 个答案:

答案 0 :(得分:3)

在讨论XML中的“元素之间的文本”时,有助于记住XML中的文本保存在Text node中。在Nokogiri中,这是一个Nokogiri::XML::Text实例。

例如,这个HTML:

<p>Hello <b>World</b>!</p>

最简单的代表是:

(Element name:"p" children:[
  (Text content:"Hello ")
  (Element name:"b" children:[
    (Text content:"World")
  ])
  (Text content:"!")
])

<p>元素有三个子节点。通常我们不需要记住这一点,因为我们经常想知道作为子或后代的文本,找到一个元素,然后使用.text方法给我们一个字符串。

在您的情况下,您希望找到最可靠的方法来定位附近的元素。我们假设<a href="...">Click here for more info</a>将始终存在,并且您想要的文本紧接在那之前。

# Find an <a> element with specific text content
info = doc.at_xpath('//a[.="Click here for more info"]')

# Walk back to the previous element, which we assume is an always-present <br>
br   = info.previous_element

# Find the Text node immediately preceding that, and then get its contents
desc = br.previous.text

我们可以使用XPath更高效,更简洁地完成这项任务,但Ruby程序员更难理解:

p doc.at('//a[.="Click here for more info"]/preceding-sibling::text()[1]').text
#=> " \nConducts research towards understanding, treating and halting the ...

上面找到了锚点,然后使用XPath查找所有前面的文本节点,然后只选择第一个文本节点。

答案 1 :(得分:2)

这个怎么样:

html = '<b>Multiple Sclerosis National Research Institute</b><br> ...'
doc = Nokogiri::HTML(html)
doc.css('br')[2].next.text.strip
#=> "Conducts research towards understanding, treating and halting the progression of multiple sclerosis and related diseases. Current research progress is promising. Please help us find cures!"

并通过直播内容:

url = "https://www.neighbortonation.org/ntn/charities/home.aspx"    
doc = Nokogiri::HTML(open(url))

doc.css("#site-pagecontent table table td").each do |item|
  description = item.css('br')[2].next.text.strip unless item.css('br').empty?
  ...
end