【问题标题】:How do you parse a poorly formatted HTML file?如何解析格式不佳的 HTML 文件?
【发布时间】:2010-10-17 04:14:21
【问题描述】:

我必须解析一系列网页才能将数据导入应用程序。每种类型的网页都提供相同类型的数据。问题是每个页面的HTML不同,所以数据的位置也不同。另一个问题是 HTML 代码的格式很差,因此无法使用类似 XML 的解析器。

到目前为止,我能想到的最佳策略是为每种页面定义一个模板,例如:

模板 A:

<html>
...
  <tr><td>Table column that is missing a td 
      <td> Another table column</td></tr>
  <tr><td>$data_item_1$</td>
...
</html>

模板 B:

<html>
...
  <ul><li>Yet another poorly formatted page <li>$data_item_1$</td></tr>
...
</html>

这样我只需要一个解析器来处理所有页面,它将每个页面与其模板进行比较并检索$data_item_1$$data_item_2$ 等。不过,这将是很多工作。你能想出更简单的解决方案吗?有什么图书馆可以帮忙吗?

谢谢

【问题讨论】:

    标签: html parsing text html-content-extraction


    【解决方案1】:

    你可以通过 tidy 传递页面的源来获取一个有效的页面。可以找齐here . Tidy 有很多编程语言的绑定。完成此操作后,您可以使用自己喜欢的解析器/内容提取技术。

    【讨论】:

    • 我完全同意。首先通过 Tidy。
    【解决方案2】:

    我推荐Html Agility Pack。它能够处理结构不佳的 HTML,同时使用 Xpath 为您提供类似 Xml 的选择。您仍然需要对项目进行模板化或使用不同的选择进行选择并进行分析,但它会让您摆脱糟糕的结构驼峰。

    【讨论】:

    • 这绝对是一个很棒的工具,值得研究。完整的源代码还包含大量示例。
    【解决方案3】:

    如之前提到的here 和其他 SO 答案,Beautiful Soup 可以解析奇怪的 HTML。

    Beautiful Soup 是一个 Python HTML/XML 解析器,专为屏幕抓取等快速周转项目而设计。三个功能使它变得强大:

    1. Beautiful Soup 不会因为你的错误标记而窒息。它会生成一个解析树,其意义与您的原始文档大致相同。这通常足以收集您需要的数据并逃跑。
    2. Beautiful Soup 提供了一些用于导航、搜索和修改解析树的简单方法和 Pythonic 习惯用法:用于剖析文档和提取所需内容的工具包。您不必为每个应用程序创建自定义解析器。
    3. Beautiful Soup 自动将传入文档转换为 Unicode,将传出文档自动转换为 UTF-8。您不必考虑编码,除非文档未指定编码并且 Beautiful Soup 无法自动检测编码。然后你只需要指定原始编码。

    Beautiful Soup 会解析你给它的任何东西,并为你做树遍历的东西。您可以告诉它“查找所有链接”,或“查找类 externalLink 的所有链接”,或“查找所有 url 匹配“foo.com”的链接,或“查找带有粗体文本的表格标题,然后给出我那个文本。”

    【讨论】:

      【解决方案4】:

      使用 HTML5 解析器,例如 html5lib

      与 HTML Tidy 不同,这将为您提供非常接近浏览器所做的错误处理。

      【讨论】:

      • HTML5 规范试图标准化浏览器用来解释格式错误的 HTML 的解析规则。 hml5lib 是 python 中规范的开放实现 - 因此,如果您使用它,您将获得与 HTML5 兼容浏览器相同的解析行为。您可以将它与 lxml 结合使用,以获得与美丽汤相似的功能。
      【解决方案5】:

      在这方面有几个 C# 特定线程,例如 Looking for C# HTML parser

      【讨论】:

        【解决方案6】:

        根据您需要提取正则表达式的数据,可能是一种选择。我知道很多人一想到在结构化数据上使用 RegEx 就会感到不寒而栗,但显而易见的事实是(正如您所发现的)许多 HTML 实际上的结构并不好,而且很难解析。

        我遇到了与您类似的问题,但在我的情况下,我只想要页面中的一个特定数据,无需解析 HTML 即可轻松识别,因此 RegEx 工作得非常好。

        【讨论】:

          猜你喜欢
          • 2011-04-26
          • 2015-02-16
          • 1970-01-01
          • 2011-05-23
          • 2016-03-11
          • 1970-01-01
          • 2018-05-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多