如何在PHP中解析和处理HTML / XML?

2022-08-30 05:44:53

如何解析HTML / XML并从中提取信息?


答案 1

本机 XML 扩展

我更喜欢使用其中一个本机XML扩展,因为它们与PHP捆绑在一起,通常比所有第三方库都快,并给我所有需要的标记控制。

多姆

DOM 扩展允许您通过带有 PHP 5 的 DOM API 对 XML 文档进行操作。它是 W3C 的文档对象模型核心级别 3 的实现,该级别是一个与平台和语言无关的接口,允许程序和脚本动态访问和更新文档的内容、结构和样式。

DOM能够解析和修改现实世界(破碎的)HTML,并且可以执行XPath查询。它基于 libxml

使用DOM需要一些时间来提高效率,但这段时间是值得的。由于DOM是一个与语言无关的接口,你会发现许多语言的实现,所以如果你需要改变你的编程语言,那么你很可能已经知道如何使用该语言的DOM API。

如何使用 DOM 扩展已在 StackOverflow 上进行了广泛的介绍,因此,如果您选择使用它,则可以确保通过搜索/浏览 Stack Overflow 可以解决您遇到的大多数问题。

其他答案中提供了基本用法示例和一般概念概述

XMLReader

XMLReader 扩展是一个 XML 拉取解析器。读取器充当在文档流上前进并在途中的每个节点处停止的光标。

XMLReader,像DOM一样,是基于libxml的。我不知道如何触发HTML解析器模块,所以使用XMLReader解析损坏的HTML可能不如使用DOM可靠,你可以明确地告诉它使用libxml的HTML解析器模块。

在另一个答案中提供了基本的用法示例

XML Parser

此扩展允许您创建 XML 分析器,然后为不同的 XML 事件定义处理程序。每个 XML 分析器还具有一些可以调整的参数。

XML 解析器库也基于 libxml,并实现了 SAX 样式的 XML 推送解析器。对于内存管理来说,它可能是比 DOM 或 SimpleXML 更好的选择,但比 XMLReader 实现的拉取解析器更难使用。

SimpleXml

SimpleXML 扩展提供了一个非常简单且易于使用的工具集,用于将 XML 转换为可以使用普通属性选择器和数组迭代器处理的对象。

SimpleXML 是一个选项,当您知道 HTML 是有效的 XHTML 时。如果你需要解析破碎的HTML,甚至不要考虑SimpleXml,因为它会窒息。

有一个基本的用法示例PHP手册中还有很多其他示例


第三方库(基于 libxml)

如果你更喜欢使用第三方库,我建议使用一个实际上在下面使用DOM/ libxml而不是字符串解析的库。

流利多姆

FluentDOM为PHP中的DOMDocument提供了一个类似jQuery的Fluent XML接口。选择器是用 XPath 或 CSS 编写的(使用 CSS 到 XPath 转换器)。当前版本扩展了DOM实现标准接口,并添加了DOM Living Standard中的功能。FluentDOM可以加载JSON,CSV,JsonML,RabbitFish等格式。可以通过 Composer 安装。

HtmlPageDom

Wa72\HtmlPageDom是一个PHP库,用于使用DOM轻松操作HTML文档。它需要来自 Symfony2 组件的 DomCrawler 来遍历 DOM 树,并通过添加用于操作 HTML 文档的 DOM 树的方法对其进行扩展。

phpQuery

phpQuery 是一个基于 jQuery JavaScript 库的服务器端、可链接的 CSS3 选择器驱动的文档对象模型 (DOM) API。该库是用 PHP5 编写的,并提供了额外的命令行界面 (CLI)。

这被描述为“废弃软件和错误:使用风险自负”,但似乎维护得很少。

层压板

Laminas\Dom 组件(以前称为 Zend_DOM)提供了用于处理 DOM 文档和结构的工具。目前,我们提供 ,它提供了一个统一的接口,用于使用XPath和CSS选择器查询DOM文档。Laminas\Dom\Query

此包被视为功能完备,现在处于仅安全维护模式。

fDOM文档

fDOMDocument 扩展了标准 DOM,以便在所有错误情况下使用异常,而不是 PHP 警告或通知。他们还添加了各种自定义方法和快捷方式,以方便并简化DOM的使用。

sabre/xml

sabre/xml 是一个库,它包装和扩展 XMLReader 和 XMLWriter 类,以创建一个简单的“xml 到对象/数组”映射系统和设计模式。写入和读取 XML 是单通道的,因此速度可能很快,并且大型 xml 文件需要较低的内存。

流体XML

FluidXML是一个PHP库,用于使用简洁流畅的API操作XML。它利用XPath和流畅的编程模式来变得有趣和有效。


第三方(不是基于 libxml)

基于 DOM/libxml 进行构建的好处是,开箱即用可以获得良好的性能,因为您基于本机扩展。但是,并非所有第三方库都沿着这条路走下去。下面列出了其中一些

PHP Simple HTML DOM Parser

  • 用 PHP5+ 编写的 HTML DOM 解析器可以让您以非常简单的方式操作 HTML!
  • 需要 PHP 5+。
  • 支持无效的 HTML。
  • 使用选择器在HTML页面上查找标签,就像jQuery一样。
  • 在一行中从 HTML 中提取内容。

我通常不建议使用这个解析器。代码库很糟糕,解析器本身相当慢,内存不足。并非所有 jQuery 选择器(如子选择器)都是可能的。任何基于 libxml 的库都应该很容易胜过这一点。

PHP Html Parser

PHPHtmlParser是一个简单,灵活的html解析器,它允许您使用任何css选择器(如jQuery)选择标签。目标是协助开发需要快速,简单的方法来抓取html的工具,无论它是否有效!这个项目最初由sunra/php-simple-html-dom-parser支持,但支持似乎已经停止,所以这个项目是我对他以前工作的改编。

同样,我不会推荐这个解析器。它相当慢,CPU使用率很高。也没有函数来清除创建的DOM对象的内存。这些问题在嵌套循环中尤其严重。文档本身不准确且拼写错误,自 2016 年 4 月 14 日以来没有对修复的响应。


HTML 5

您可以使用上述内容来解析HTML5,但是由于HTML5允许的标记,可能会有一些怪癖。因此,对于HTML5,您可能需要考虑使用专用的解析器。请注意,这些是用PHP编写的,因此与较低级别语言的编译扩展相比,性能较低且内存使用量增加。

HTML5DomDocument

HTML5DOMDocument扩展了原生DOMDocument库。它修复了一些错误并添加了一些新功能。

  • 保留 html 实体(DOMDocument 不保留)
  • 保留 void 标记(DOMDocument 不保留)
  • 允许插入将正确部件移动到正确位置的 HTML 代码(头部元素插入头部,身体元素插入正文)
  • 允许使用 CSS 选择器查询 DOM(当前可用:、和 .)*tagnametagname#id#idtagname.classname.classnametagname.classname.classname2.classname.classname2tagname[attribute-selector][attribute-selector]div, pdiv pdiv > pdiv + pp ~ ul
  • 添加对元素>类列表的支持。
  • 添加对元素>innerHTML 的支持。
  • 添加对元素>outerHTML 的支持。

HTML5

HTML5是一个完全用PHP编写的符合标准的HTML5解析器和编写器。它很稳定,在许多生产网站上使用,下载量超过500万次。

HTML5 提供了以下功能。

  • HTML5 序列化程序
  • 支持 PHP 命名空间
  • 作曲家支持
  • 基于事件(类似 SAX)的解析器
  • DOM 树生成器
  • 与查询路径的互操作性
  • 在 PHP 5.3.0 或更高版本上运行

正则表达式

最后也是最不推荐的,您可以使用正则表达式从 HTML 中提取数据。通常,不鼓励在 HTML 上使用正则表达式。

您会在 Web 上找到的大多数匹配标记的代码段都很脆弱。在大多数情况下,它们只适用于非常特定的HTML片段。微小的标记更改(如在某处添加空格,或在标记中添加或更改属性)可能会使正则表达式在未正确编写时失败。在HTML上使用正则表达式之前,您应该知道自己在做什么。

HTML解析器已经知道HTML的语法规则。必须为您编写的每个新正则表达式授课。正则表达式在某些情况下很好,但它实际上取决于您的用例。

您可以编写更可靠的解析器,但是当上述库已经存在并且在这方面做得更好时,使用正则表达式编写完整可靠的自定义解析器是浪费时间。

另请参阅解析 Html 克苏鲁方式


如果你想花一些钱,看看

我不隶属于PHP架构师或作者。


答案 2

尝试简单的HTML DOM Parser

  • 用PHP 5 +编写的HTML DOM解析器,可让您以非常简单的方式操作HTML!
  • 需要 PHP 5+。
  • 支持无效的 HTML。
  • 使用选择器在HTML页面上查找标签,就像jQuery一样。
  • 在一行中从 HTML 中提取内容。
  • 下载

注意:顾名思义,它对于简单的任务很有用。它使用正则表达式而不是HTML解析器,因此对于更复杂的任务,它将相当慢。其大部分代码库是在2008年编写的,从那时起只做了一些小的改进。它不遵循现代PHP编码标准,并且很难将其合并到符合PSR标准的现代项目中。

例子:

如何获取 HTML 元素:

// Create DOM from URL or file
$html = file_get_html('http://www.example.com/');

// Find all images
foreach($html->find('img') as $element)
       echo $element->src . '<br>';

// Find all links
foreach($html->find('a') as $element)
       echo $element->href . '<br>';

如何修改 HTML 元素:

// Create DOM from string
$html = str_get_html('<div id="hello">Hello</div><div id="world">World</div>');

$html->find('div', 1)->class = 'bar';

$html->find('div[id=hello]', 0)->innertext = 'foo';

echo $html;

从 HTML 中提取内容:

// Dump contents (without tags) from HTML
echo file_get_html('http://www.google.com/')->plaintext;

刮擦斜杠点:

// Create DOM from URL
$html = file_get_html('http://slashdot.org/');

// Find all article blocks
foreach($html->find('div.article') as $article) {
    $item['title']     = $article->find('div.title', 0)->plaintext;
    $item['intro']    = $article->find('div.intro', 0)->plaintext;
    $item['details'] = $article->find('div.details', 0)->plaintext;
    $articles[] = $item;
}

print_r($articles);

推荐