【问题标题】:Find important text in arbitrary HTML using PHP?使用 PHP 在任意 HTML 中查找重要文本?
【发布时间】:2011-07-18 10:01:22
【问题描述】:

我有一些随机的 HTML 布局,其中包含我想提取的重要文本。我不能只是strip_tags(),因为这会在侧边栏/页脚/页眉/等中留下一堆额外的垃圾。

我找到了method built in Python,我想知道 PHP 中是否有类似的东西。

这个概念相当简单:使用 关于文本密度的信息 与 HTML 代码相比,如果一行 文本值得输出。 (这不是 一个新颖的想法,但它有效!) 流程如下:

  1. 解析 HTML 代码并跟踪处理的字节数。
  2. 按行或按段落存储文本输出。
  3. 与每个文本行相关联所需的 HTML 字节数 描述一下。
  4. 通过计算文本的比例来计算每行的文本密度 t> o 个字节。
  5. 然后使用神经网络确定该行是否是内容的一部分。

你可以得到很好的结果 通过检查线的密度是否为 高于固定阈值(或 平均),但系统使更少 如果你使用机器学习会出错 - 更不用说它更容易 实施!

更新:我开始悬赏一个可以从随机 HTML 模板中提取主要内容的答案。由于我无法共享我将使用的文档 - 只需选择任何随机博客站点并尝试从布局中提取正文。请记住,页眉、侧边栏和页脚也可能包含文本。有关想法,请参阅上面的链接。

【问题讨论】:

  • 您所说的“提取”是什么意思 - 使用完整的 HTML(如 <b><i><a>)提取,还是仅提取文本?
  • 我不会重新实现这个。要么直接使用python模块$text = exec("python -m ..."),要么使用在线服务boilerpipe-web.appspot.com
  • @Pekka,我宁愿将标记元素(如代码块或对象嵌入)与文本一起使用——但纯文本也可以。 @mario - 谢谢!这看起来是一个好的开始——但我确实需要可以在本地运行的东西,如果可能的话,我宁愿不将 Java 添加到我的服务器应用程序中。
  • (related) Best Methods to parse HTML 使用标记。对于密度和东西,你必须找到一些额外的工具。
  • 您可能正在寻找类似可读性算法的东西,请参阅此问题以获取更多信息和实现:stackoverflow.com/questions/1146934/…

标签: php regex dom text-parsing


【解决方案1】:
  • phpQuery 是一个基于 jQuery JavaScript 库的服务器端、可链接、CSS3 选择器驱动的文档对象模型 (DOM) API。

更新 2

  1. 很多博客都使用CMS
  2. blogs html 结构几乎是一样的。
  3. 避免使用常见的选择器,如#sidebar, #header, #footer, #comments, etc..
  4. 通过标签名称script, iframe避免任何小部件
  5. 清除众所周知的内容,例如:
    1. /\d+\scomment(?:[s])/im
    2. /(read the rest|read more).*/im
    3. /(?:.*(?:by|post|submitt?)(?:ed)?.*\s(at|am|pm))/im
    4. /[^a-z0-9]+/im

搜索众所周知的类和 ID:

  • typepad.com .entry-content
  • wordpress.org .post-entry .entry .post
  • movabletype.com .post
  • blogger.com .post-body .entry-content
  • drupal.com .content
  • tumblr.com .post
  • squarespace.com .journal-entry-text
  • 表达式引擎.com .entry
  • gawker.com .post-body

  • 参考:The blog platforms of choice among the top 100 blogs


$selectors = array('.post-body','.post','.journal-entry-text','.entry-content','.content');
$doc = phpQuery::newDocumentFile('http://blog.com')->find($selectors)->children('p,div');

基于如下所示的常见 html 结构进行搜索:

<div>
<h1|h2|h3|h4|a />
<p|div />
</div>

$doc = phpQuery::newDocumentFile('http://blog.com')->find('h1,h2,h3,h4')->parent()->children('p,div');

【讨论】:

  • 太棒了,我可能不会使用它 - 但我又开始了另一个赏金计划,因为我确信其他人可以使用它。
【解决方案2】:

Domdocument可以用来解析html文档,然后可以通过PHP查询。

编辑:维基百科

【讨论】:

  • 是的,我目前正在试验它和正则表达式,并祝你好运。如果你在 PHP 中禁用了 E_WARNING 错误并通过 loadHTML() 加载内容,你甚至可以很好地解析无效的 HTML。
  • 在构建 Regex HTML 解析器(75% 成功率)和 DOM 解析器(90% 成功率)之后。如果没有人想提供一些解析 HTML 的示例,我将不得不奖励这个基本答案。对于任何关心的人,值得注意的是,使用我的 ~10 条正则表达式规则解析 HTML 比使用 PHP DOM 快 10 倍。但是,对于我必须使用 preg 函数创建的所有额外匹配数组,PHP DOM 使用的 RAM 减少了 25%。
  • 能否提供您编写的 DOM 解析器解决方案?
【解决方案3】:

不久前我从事过一个类似的项目。它不像 Python 脚本那么复杂,但它会做得很好。查看简单的 HTML PHP 解析器

http://simplehtmldom.sourceforge.net/

【讨论】:

  • 这只是一个普通的 DOM 解析器,它需要你知道布局才能找到你需要的东西。这些是我正在使用的任意 HTML 文件,因此它们的结构通常非常不同。
  • @Xeon 不一定:您可以遍历每个元素并检查其textNode 值(或simpleHTMLDOM 中文本节点的名称)。如果它与您的搜索模式匹配,则拉出包括子元素在内的整个元素。这是我能想到的唯一方法......但是有 SimpleHTMLDOM 的替代品,请参阅stackoverflow.com/questions/3577641/best-methods-to-parse-html/…
  • 谢谢佩卡。没错,Xeoncross,您可以遍历整个文档,获取元素及其子元素,甚至可能运行递归解析。
  • 来自 SO 链接 Pekka 的替代品列表。 :)
  • 获取一个元素及其子元素并不像听起来那么容易。如果可以提供一个工作示例,我很乐意将此作为答案。
【解决方案4】:

根据您的 HTML 结构,如果您有 id 或类,您可能会有点复杂,并使用 preg_match() 专门获取某个开始和结束标记之间的任何信息。这意味着您应该知道如何编写正则表达式。

您还可以查看浏览器仿真 PHP 类。我已经为页面抓取完成了此操作,并且根据 DOM 的格式化程度,它的效果是否足够好。我个人喜欢 SimpleBrowser
http://www.simpletest.org/api/SimpleTest/WebTester/SimpleBrowser.html

【讨论】:

  • 用 PHP 编写的浏览器是吗?有趣的想法。至于正则表达式,我遇到的问题是,虽然在一些连续布局的文档上搜索文本很容易,但在部分之间有一堆垃圾的其他文档很难找到。
  • 如果您正在解析动态变化的文档,使用任何方法都无法捕获您想要的所有数据,因此您必须在每个文档的基础上不断调整。如果您可以在所有文档之间找到一个共同点,例如#content 的 id,这将使事情变得更容易。使用带有 preg_match 的正则表达式编写和调整可能会很乏味。只要您知道文档 DOM,SimpleBrowser 将让您找到任何元素并遍历其子元素,从而使其更容易调整。越具体越好,但您可以定位一个元素,即使它没有类或 ID。
  • 是的,文档之间有很多差异。这是我发现的一些相似之处。所有文档在 cmets 之前都有主要内容(如果存在 cmets)。所有内容通常是父 div 的很大一部分(使用 DOM 解析时)。文本内容的开头通常是文本与 html 的较高比例(使用正则表达式解析时),尽管文本部分之间可以有示例、视频嵌入和代码。
【解决方案5】:

我开发了一个可用于此目的的HTML parser and filter PHP 包。

它由一组类组成,这些类可以链接在一起以在 HTML/XML 代码中执行一系列解析、过滤和转换操作。

它是为了处理现实世界的页面,所以它可以处理格式错误的标签和数据结构,所以它可以尽可能多地保留原始文档。

它附带的一个过滤器类可以进行 DTD 验证。另一个可以丢弃不安全的 HTML 标签和 CSS 来防止 XSS 攻击。另一个可以简单地提取所有文档链接。

所有这些过滤器类都是可选的。如果需要,您可以按照自己的方式将它们链接在一起。

所以,为了解决您的问题,我认为 PHP 中没有任何特定的解决方案,但可以为它开发一个特殊的过滤器类。看看包装。它有详尽的记录。

如果您需要帮助,只需查看我的个人资料并给我发邮件,我什至可以开发完全满足您需求的过滤器,最终启发其他语言存在的任何解决方案。

【讨论】:

    猜你喜欢
    • 2013-03-27
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多