如何使用Hpricot从带有标签的网页中提取文本?

时间:2010-12-08 18:57:14

标签: ruby hpricot

我正在尝试使用Hpricot和Ruby解析HTML文件,但我在提取“自由浮动”文本时遇到问题,该文本未包含在<p></p>等标记中。

require 'hpricot'

text = <<SOME_TEXT
  <a href="http://www.somelink.com/foo/bar.html">Testing:</a><br />
  line 1<br />  
  line 2<br />
  line 3<br />
  line 4<br />
  line 5<br />
  <b>Here's some more text</b>
SOME_TEXT

parsed = Hpricot(text)

parsed = parsed.search('//a[@href="http://www.somelink.com/foo/bar.html"]').first.following_siblings
puts parsed

我希望结果是

<br />
line 1<br />  
line 2<br />
line 3<br />
line 4<br />
line 5<br />
<b>Here's some more text</b>

但我得到了

<br />
<br />
<br />
<br />
<br />
<br />
<b>Here's some more text</b>

如何让Hpricot返回第1行,第2行等?

2 个答案:

答案 0 :(得分:1)

您的第一步是阅读following_siblings文档:

  

查找跟随当前元素的兄弟元素。与其他“兄弟”方法一样,此清除文本和注释节点

然后你应该使用Hpricot源来概括following_siblings如何工作以获得像following_siblings那样的东西,但不会过滤掉非容器节点:

parsed        = Hpricot(text)
link          = parsed.search('//a[@href="http://www.somelink.com/foo/bar.html"]').first
link_sibs     = link.parent.children
what_you_want = link_sibs[link_sibs.index(link) + 1 ... link_sibs.length]

puts what_you_want

following_siblings而不是parent.children相当parent.containers。访问您使用的库的源代码非常方便,应该鼓励学习它。

答案 1 :(得分:0)

自从我使用Hpricot已经有一段时间了,但是我记得有些事情可能有所帮助:

快速获取所有文字的方法:

irb(main):023:0> print parsed.inner_text
  Testing:
  line 1  
  line 2
  line 3
  line 4
  line 5
  Here's some more text

缺点是你也将文本嵌入标签中。

同样,我们可以搜索所有'text()'个节点:

irb(main):033:0> puts (parsed / 'text()')

Testing:

  line 1

  [...]

  line 5

所以,我们可以这样做:

irb(main):036:0> puts (parsed / 'text()')[2 .. -3]

  line 1

  line 2

  line 3

  line 4

  line 5

或:

irb(main):037:0> (parsed / 'text()')[2 .. -3]
=> #<Hpricot::Elements["\n  line 1", "  \n  line 2", "\n  line 3", "\n  line 4", "\n  line 5", "\n  "]>

或:

irb(main):039:0> (parsed / 'text()')[2 .. -3].map{ |t| t.inner_text.strip }
=> ["line 1", "line 2", "line 3", "line 4", "line 5", ""]

从网页抓取数据/文本的主要想法是查找可用于浏览页面的地标。我们通常可以从<div><p>标记内抓取文字。如果页面没有给你标记,你必须使用其他技巧;可能会查找一系列文本节点,后跟<br>个节点,或者<a>标记后面的五行,并且具有某个href属性。这是处理HTML的乐趣和挑战。

在我的脑海里,有一种唠叨的想法,有一种更优雅的方式来做到这一点,但这似乎是有效的。在Hpricot Challenge page上挖掘有关挖掘内容主题的变体。