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

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

技术背景

在PHP开发中,经常需要解析和处理HTML/XML数据。例如,在进行网页数据抓取、数据转换等操作时,都需要对HTML/XML进行解析。PHP提供了多种方式来实现这一需求,不同的方法适用于不同的场景。

实现步骤

原生XML扩展

  • DOM:允许通过DOM API操作XML文档,基于libxml,能解析和修改真实世界中的(有缺陷的)HTML,还能进行XPath查询。
1
2
3
4
5
// 示例代码:使用DOM解析HTML
$dom = new DOMDocument();
@$dom->loadHTML('<html><body><h1>Hello, World!</h1></body></html>');
$h1 = $dom->getElementsByTagName('h1')->item(0);
echo $h1->textContent;
  • XMLReader:是一个XML拉取解析器,基于libxml,像游标一样在文档流上向前移动并在每个节点处停止。
1
2
3
4
5
6
7
8
9
// 示例代码:使用XMLReader解析XML
$reader = new XMLReader();
$reader->open('example.xml');
while ($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'item') {
echo $reader->readInnerXML();
}
}
$reader->close();
  • XML Parser:可创建XML解析器并为不同的XML事件定义处理程序,基于libxml,实现了SAX风格的XML推式解析器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 示例代码:使用XML Parser解析XML
$parser = xml_parser_create();
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "characterData");
$xml = '<root><item>Value</item></root>';
xml_parse($parser, $xml);
xml_parser_free($parser);

function startElement($parser, $name, $attrs) {
echo "Start element: $name\n";
}

function endElement($parser, $name) {
echo "End element: $name\n";
}

function characterData($parser, $data) {
echo "Character data: $data\n";
}
  • SimpleXml:当HTML是有效的XHTML时可使用,它能将XML转换为对象,可通过普通属性选择器和数组迭代器进行处理。
1
2
3
4
// 示例代码:使用SimpleXml解析XML
$xml = '<root><item>Value</item></root>';
$simpleXml = simplexml_load_string($xml);
echo $simpleXml->item;

第三方库(基于libxml)

  • FluentDom:为PHP中的DOMDocument提供类似jQuery的流畅XML接口,可通过XPath或CSS选择器进行选择。
  • HtmlPageDom:使用DOM轻松操作HTML文档的PHP库,依赖于Symfony2组件的DomCrawler。
  • phpQuery:基于jQuery JavaScript库的服务器端、可链式调用、由CSS3选择器驱动的DOM API。
  • laminas-dom:提供处理DOM文档和结构的工具,提供统一的接口来使用XPath和CSS选择器查询DOM文档。
  • fDOMDocument:扩展了标准DOM,在所有错误情况下使用异常而不是PHP警告或通知。
  • sabre/xml:包装和扩展了XMLReader和XMLWriter类,创建了一个简单的“xml到对象/数组”映射系统和设计模式。
  • FluidXML:用于操作XML的PHP库,具有简洁流畅的API。

第三方库(非基于libxml)

  • PHP Simple HTML DOM Parser:用PHP5+编写的HTML DOM解析器,支持无效HTML,可像jQuery一样使用选择器查找标签。但代码库较差,解析速度慢且占用内存多。
1
2
3
4
5
6
// 示例代码:使用PHP Simple HTML DOM Parser解析HTML
include('simple_html_dom.php');
$html = file_get_html('http://www.example.com/');
foreach ($html->find('img') as $element) {
echo $element->src . '<br>';
}
  • PHP Html Parser:简单灵活的HTML解析器,可使用任何CSS选择器选择标签。但速度较慢,CPU使用率高,且没有清除创建的DOM对象内存的功能。

HTML 5解析

  • HTML5DomDocument:扩展了原生DOMDocument库,修复了一些错误并添加了一些新功能。
  • HTML5:完全用PHP编写的符合标准的HTML5解析器和编写器,稳定且在许多生产网站中使用。

正则表达式

虽然不推荐,但在某些特定情况下可以使用正则表达式从HTML中提取数据。不过,正则表达式对HTML的匹配通常很脆弱,微小的标记变化可能导致正则表达式失败。

1
2
3
4
5
6
// 示例代码:使用正则表达式提取HTML中的图片URL
$html = '<html><body><img src="example.jpg"></body></html>';
preg_match_all('/<img\s+src="([^"]+)"/', $html, $matches);
foreach ($matches[1] as $src) {
echo $src . '<br>';
}

最佳实践

  • 优先使用原生XML扩展,因为它们通常更快且能提供更多的控制。
  • 当处理有效的XHTML时,可考虑使用SimpleXml。
  • 对于需要类似jQuery操作的场景,可选择基于libxml的第三方库,如FluentDom、phpQuery等。
  • 尽量避免使用正则表达式解析HTML,除非是非常简单的任务。

常见问题

  • 解析有缺陷的HTML:可使用DOM扩展,它能处理一些有缺陷的HTML。也可使用HTML Tidy先清理HTML,将其转换为XHTML后再进行解析。
  • 性能问题:使用基于原生扩展的方法和库通常能获得更好的性能。避免使用性能较差的第三方库,如PHP Simple HTML DOM Parser和PHP Html Parser。
  • 正则表达式匹配失败:正则表达式对HTML的微小变化很敏感,应谨慎使用。如果必须使用,要确保正则表达式的编写考虑到可能的变化。

在PHP中如何解析和处理HTML/XML
https://119291.xyz/posts/php-html-xml-parsing/
作者
ww
发布于
2025年5月16日
许可协议