从HTML页面中提取内容(不包括导航)的Python方法

8
当然,可以使用任何数量的Python解析器来解析HTML页面,但我很惊讶似乎没有公开的解析脚本来从给定的HTML文档中提取有意义的内容(不包括侧栏、导航等)。我猜这就像收集DIV和P元素,然后检查它们是否具有最少量的文本内容,但我相信一个稳健的实现将包含我没有想到的很多东西。

1
这个用于可读性书签的JS脚本似乎运行得非常出色:http://lab.arc90.com/experiments/readability/js/readability.js - JJ.
“meaningful”是什么意思?程序可以使用什么规则来区分“有意义”的内容和应该被排除的内容?这个规则是否适用于所有情况? - S.Lott
所谓“有意义”,我指的是可读性提取的内容类型。显然,这在某些类型的网站上效果不佳,但我主要关注的是博客和新闻网站,您希望从中提取最大的文本块。 - JJ.
你说得很对,为什么没有针对这个问题的库?因为这个问题非常普遍,所以应该有相应的解决方案。顺便问一下:你是怎么解决自己的问题的? - Thomas Uhrig
5个回答

5
尝试使用Python的Beautiful Soup库。它有非常简单的方法从html文件中提取信息。
试图通用地从网页中提取数据需要人们以类似的方式编写页面...但是,即使外观相同,传达页面的方式也有无数种组合,更不用说传达相同信息的所有组合了。
您是否在尝试提取特定类型的信息或其他目标?
您可以尝试提取“div”和“p”标记中的任何内容,并比较页面中所有信息的相对大小。然后问题就是人们可能会将信息分组到“div”和“p”的集合中(或者至少如果他们编写的是格式良好的html!)。
也许,如果您形成了信息关系的树(节点将是'p'或'div'或其他任何内容,每个节点将包含相关文本),则可以进行某种分析来识别包含大多数信息的最小'p'或'div'?

[编辑] 如果您能将它放入我建议的树形结构中,那么您就可以使用类似于垃圾邮件刺客的类似积分系统。定义一些规则来尝试对信息进行分类。以下是一些示例:

+1 points for every 100 words
+1 points for every child element that has > 100 words
-1 points if the section name contains the word 'nav'
-2 points if the section name contains the word 'advert'

如果你有很多低评分规则,当你找到更相关的部分时它们会累加,我认为这可能会演变成一种相当强大和健壮的技术。

[编辑2] 从可读性来看,它似乎正在完全按照我刚才提出的建议执行!也许可以改进以更好地理解表格?


这正是我所想的,但我仍然感到惊讶的是,为什么没有一个简单的库或BeautifulSoup插件可以为您完成这项工作,因为我想从HTML中提取内容时,90%以上的情况下都可以使用这些规则... - JJ.
这真的取决于你想要什么;我写过的几乎每个爬虫都是在寻找大量小片段的信息,而不是更大的文本块(这些通常是关于网站的通用信息)。 - Jon Cage
另外一个有趣的侧面是:基于JavaScript的“可读性”脚本也可以进行内容提取(或者说选择)。它也可以被剥离出来作为想法/算法。虽然它并不总是成功的。 - HoverHell

4
请看templatemaker:http://www.holovaty.com/writing/templatemaker/。它是由Django的创始人之一编写的。基本上,您将几个示例html文件提供给它,它将生成一个“模板”,然后您可以使用该模板提取仅有所不同的部分(通常是有意义的内容)。
以下是来自google code page的示例:
# 导入Template类。 >>> from templatemaker import Template # 创建一个Template实例。 >>> t = Template()
# 学习样本字符串。 >>> t.learn('<b>this and that</b>')
# 输出到目前为止的模板,使用“!”字符标记空洞。 # 我们只学了一个字符串,因此模板没有空洞。 >>> t.as_text('!') '<b>this and that</b>'
# 学习另一个字符串。 True返回值表示模板至少获得了一个空洞。 >>> t.learn('<b>alex and sue</b>') True # 的确,模板现在有了一些空洞。 >>> t.as_text('!') '<b>! and !</b>'

3
你可以使用boilerpipe Web应用程序来动态获取和提取内容。 (这不仅适用于Python,因为您只需要对Google AppEngine上的页面发出HTTP GET请求即可)。 祝好, Christian

乍一看,这看起来非常不错。如果有一个像这样的库就好了。谢谢! - Thomas Uhrig

1
什么是有意义的,什么不是,这取决于页面的语义。如果语义差,你的代码就无法“猜测”什么是有意义的。我使用可读性插件,就像你在评论中链接的那样,我发现在许多我尝试阅读的页面上它都没有提供任何结果,更不用说体面的结果了。
如果有人把内容放在表格中,你就完蛋了。试试在 phpbb 论坛上使用可读性插件,你就会明白我的意思。
如果你想做到这一点,可以使用 <p></p> 的正则表达式,或者解析 DOM。

如果你查看源代码,你会发现即使是 StackOverflow 在某些地方也使用表格进行布局!! - Jon Cage
但是它的文本是段落形式,而不是像糟糕的论坛一样只在单元格中!也无需大声喊叫! - zalew
非常正确,我只是惊讶于SO使用表格进行布局。当然,表格通常更可靠地呈现,但是对于可读性来说,CSS和更多的'div'和'p'会是更好的解决方案(例如,屏幕阅读器在处理表格时会遇到更多问题)。 - Jon Cage

0

Goose是这项任务的库。引用他们的README:

Goose将尝试提取以下信息:

  • 文章的主要文本
  • 文章的主要图像
  • 文章中嵌入的任何Youtube/Vimeo视频
  • 元描述
  • 元标签

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接