如何解析HTML/XML并从中提取信息?
当前回答
本机XML扩展
我更喜欢使用一种原生XML扩展,因为它们与PHP捆绑在一起,通常比所有第三方库都快,并为我提供了对标记所需的所有控制。
DOM
DOM扩展允许您使用PHP5通过DOMAPI对XML文档进行操作。它是W3C文档对象模型核心级别3的实现,这是一个平台和语言中立的界面,允许程序和脚本动态访问和更新文档的内容、结构和样式。
DOM能够解析和修改真实世界(已损坏)的HTML,并且可以执行XPath查询。它基于libxml。
使用DOM需要一些时间来提高效率,但这段时间是值得的。由于DOM是一种语言无关的接口,您可以找到多种语言的实现,因此如果您需要更改编程语言,那么您很可能已经知道如何使用该语言的DOM API。
StackOverflow上已经详细介绍了如何使用DOM扩展,因此如果您选择使用它,您可以确保通过搜索/浏览StackOverload来解决您遇到的大多数问题。
其他答案中提供了基本用法示例和一般概念概述。
解析器
XMLReader扩展是一个XML拉式解析器。读取器充当文档流上前进的光标,并在途中的每个节点处停止。
XMLReader与DOM一样,基于libxml。我不知道如何触发HTML解析器模块,因此使用XMLReader解析损坏的HTML可能比使用DOM更不可靠,在DOM中可以明确告诉它使用libxml的HTML解析器模块。
另一个答案中提供了一个基本用法示例。
解析器
此扩展允许您创建XML解析器,然后为不同的XML事件定义处理程序。每个XML解析器也有一些可以调整的参数。
XML解析器库也基于libxml,并实现SAX风格的XML推送解析器。对于内存管理,它可能比DOM或SimpleXML更好,但比XMLReader实现的pull解析器更难使用。
简单XML
SimpleXML扩展提供了一个非常简单且易于使用的工具集,用于将XML转换为可以使用普通属性选择器和数组迭代器处理的对象。
当您知道HTML是有效的XHTML时,SimpleXML是一个选项。如果您需要解析损坏的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安装。
HTML页面域
Wa72\HtmlPageDom是一个易于操作HTML的PHP库使用DOM的文档。它需要Symfony2的DomCrawler用于遍历的组件DOM树,并通过添加用于操作HTML文档的DOM树。
php查询
phpQuery是一个基于jQueryJavaScript库的服务器端、可链接的CSS3选择器驱动的文档对象模型(DOM)API。该库使用PHP5编写,并提供了额外的命令行界面(CLI)。
这被描述为“废弃软件和bug:使用风险自负”,但似乎维护得很少。
薄层dom
Laminas\Dom组件(以前称为Zend_Dom)提供了处理Dom文档和结构的工具。目前,我们提供Laminas\Dom\Query,它为使用XPath和CSS选择器查询Dom文档提供了统一的接口。此软件包被视为功能完整,现在处于仅安全维护模式。
fDOM文件
fDOMDocument扩展了标准DOM,在所有错误情况下都使用异常,而不是PHP警告或通知。为了方便和简化DOM的使用,他们还添加了各种自定义方法和快捷方式。
sa刀/xml
sabre/xml是一个库,它包装并扩展XMLReader和XMLWriter类,以创建一个简单的“xml到对象/数组”映射系统和设计模式。编写和读取XML是一次性的,因此速度很快,对大型XML文件的内存要求很低。
流体XML
FluidXML是一个PHP库,用于使用简洁流畅的API操作XML。它利用XPath和流畅的编程模式,使其变得有趣和有效。
第三方(非基于libxml)
基于DOM/libxml构建的好处是,由于您基于本机扩展,因此可以立即获得良好的性能。然而,并不是所有的第三方libs都走这条路。其中一些列在下面
PHP简单HTML DOM解析器
用PHP5+编写的HTML DOM解析器可以让您以非常简单的方式操作HTML!需要PHP 5+。支持无效的HTML。使用类似jQuery的选择器在HTML页面上查找标记。从HTML中提取单行内容。
我通常不建议使用此解析器。代码库很糟糕,解析器本身也很慢,内存不足。并非所有jQuery选择器(如子选择器)都是可能的。任何基于libxml的库都应该很容易地胜过这一点。
PHP Html解析器
PHPHtmlParser是一个简单、灵活的html解析器,它允许您使用任何css选择器(如jQuery)选择标记。目标是帮助开发需要快速、简单的方式来抓取html的工具,无论它是否有效!这个项目最初由sunra/php简单的html dom解析器支持,但支持似乎已经停止,所以这个项目是我对他以前工作的改编。
同样,我不建议使用此解析器。由于CPU使用率高,速度相当慢。也没有清除创建的DOM对象的内存的功能。这些问题尤其适用于嵌套循环。文档本身不准确,拼写错误,自2016年4月14日以来,没有对修复进行回复。
HTML 5
您可以使用上面的方法来解析HTML5,但由于HTML5允许的标记,可能会有一些奇怪之处。因此,对于HTML5,您可能需要考虑使用专用解析器。请注意,这些都是用PHP编写的,因此与使用较低级别语言编译的扩展相比,性能更慢,内存使用量更大。
HTML5DomDocument
HTML5DOMDocument扩展了本机DOMDocument库。它修复了一些错误并添加了一些新功能。保留html实体(DOMDocument不保留)保留空标记(DOMDocument不保留)允许插入HTML代码,将正确的部分移动到正确的位置(头部元素插入头部,身体元素插入身体)允许使用CSS选择器查询DOM(当前可用:*、标记名、标记名#id、#id、tagname.classname、.classname,tagname.cclassname2、.classname2、标记名[attribute selector]、[attributeselector],div、p、div p、div>p、div+p和p~ul)添加对元素->classList的支持。添加对元素->innerHTML的支持。添加对元素->outerHTML的支持。
HTML5
HTML5是完全用PHP编写的符合标准的HTML5解析器和编写器。它是稳定的,在许多制作网站中使用,下载量超过500万。HTML5提供以下功能。
HTML5序列化程序支持PHP命名空间作曲家支持基于事件(类似SAX)的解析器DOM树生成器与QueryPath的互操作性在PHP 5.3.0或更高版本上运行
正则表达式
最后也是最不推荐的,您可以使用正则表达式从HTML中提取数据。通常不鼓励在HTML上使用正则表达式。
你在网上找到的大多数与标记匹配的代码片段都很脆弱。在大多数情况下,它们只适用于一段非常特殊的HTML。微小的标记更改,如在某处添加空白,或在标记中添加或更改属性,可能会导致RegEx在未正确编写时失败。在HTML上使用RegEx之前,您应该知道自己在做什么。
HTML解析器已经知道HTML的语法规则。必须为您编写的每个新RegEx教授正则表达式。RegEx在某些情况下是可以的,但它确实取决于您的用例。
您可以编写更可靠的解析器,但使用正则表达式编写完整可靠的自定义解析器是浪费时间的,因为前面提到的库已经存在,并且在这方面做得更好。
另请参见解析Html Cthulhu方法
书
如果你想花钱,看看
PHP架构师使用PHP进行Web抓取的指南
我不属于PHP架构师或作者。
其他回答
有很多方法:
一般来说:
本机XML扩展:它们与PHP捆绑在一起,通常比所有第三方库都快,并为我提供了对标记所需的所有控制。DOM:DOM能够解析和修改真实世界(损坏的)HTML,并且可以执行XPath查询。它基于libxml。XMLReader:XMLReader与DOM一样,基于libxml。XMLReader扩展是一个XML拉式解析器。读取器充当文档流上前进的光标,并在途中的每个节点处停止XML解析器:此扩展允许您创建XML解析器,然后为不同的XML事件定义处理程序。每个XML解析器也有一些可以调整的参数。它实现了SAX风格的XML推送解析器。简单XML:SimpleXML扩展提供了一个非常简单且易于使用的工具集,用于将XML转换为可以使用普通属性选择器和数组迭代器处理的对象。
第三方库[libxml-based]:
FluentDom-Repo:FluentDom为PHP中的DOMDocument提供了一个类似jQuery的fluent XML接口。它可以加载JSON、CSV、JsonML、RabbitFish等格式。可以通过Composer安装。HtmlPageDom:是一个PHP库,使用它可以方便地操纵HTML文档。它需要Symfony2组件的DomCrawler来遍历DOM树,并通过添加操纵HTML文档的DOM树的方法来扩展它。ZendDOM:Zend_Dom提供了处理Dom文档和结构的工具。目前,他们提供了Zend_Dom_Query,它为使用XPath和CSS选择器查询Dom文档提供了统一的接口。QueryPath:QueryPath是一个用于处理XML和HTML的PHP库。它不仅设计用于本地文件,还设计用于web服务和数据库资源。它实现了大部分jQuery接口(包括CSS样式选择器),但它针对服务器端使用进行了大量调整。可以通过Composer安装。fDOM文档:fDOMDocument扩展了标准DOM,以在所有错误情况下使用异常,而不是PHP警告或通知。为了方便和简化DOM的使用,他们还添加了各种自定义方法和快捷方式。Sabre/XML:ssabre/XML是一个库,它包装并扩展XMLReader和XMLWriter类,以创建一个简单的“XML到对象/数组”映射系统和设计模式。编写和读取XML是一次性的,因此速度很快,对大型XML文件的内存要求很低。FluidXML:FluidXML是一个PHP库,用于使用简洁流畅的API处理XML。它利用XPath和流畅的编程模式,使其变得有趣和有效。
第三方库[不基于libxml]:
PHP简单HTML DOM解析器:一个用PHP5+编写的HTML DOM解析器允许您以非常简单的方式操作HTML,它需要PHP 5+。还支持无效的HTML。它在单行中从HTML中提取内容。代码库很糟糕,而且工作速度很慢。PHPHtmlParser:HPHtmlParser是一个简单、灵活的Html解析器,允许您使用任何CSS选择器(如jQuery)选择标记。目标是帮助开发需要快速、简单的方式来抓取HTML的工具,无论它是否有效。它速度慢,占用了太多CPU电源。Ganon(推荐):通用标记器和HTML/XML/RSS DOM解析器。它具有操纵元素及其属性的能力。它支持无效的HTML和UTF8。它可以对元素执行类似CSS3的高级查询(如jQuery——支持名称空间)。HTML美化器(如HTML Tidy)。精简CSS和Javascript。它对属性进行排序、更改字符大小写、正确缩进等。可扩展。操作分为较小的功能,便于覆盖和快速且易于使用。
Web服务:
如果您不想编写PHP,也可以使用Web服务。ScraperWiki的外部界面允许您以您希望在web或自己的应用程序中使用的形式提取数据。您还可以提取有关任何刮刀状态的信息。
我已经分享了所有的资源,你可以根据自己的口味、用途等进行选择。
QueryPath很好,但要小心“跟踪状态”,因为如果你没有意识到它的含义,这可能意味着你浪费了大量调试时间,试图找出发生了什么以及代码为什么不工作。
这意味着对结果集的每一次调用都会修改对象中的结果集,这与jquery中的每个链接都是一个新的集一样是不可链接的,您有一个单独的集,它是查询的结果,而每个函数调用都会更改该单独的集。
为了获得类似jquery的行为,您需要在执行类似过滤器/修改的操作之前进行分支,这意味着它将更紧密地反映jquery中发生的情况。
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$results现在包含输入的结果集[name='rename']而不是原始查询“div p”。这让我很困惑,我发现QueryPath跟踪过滤器和查找结果,以及修改结果并将其存储在对象中的所有内容。你需要这样做
$forename = $results->branch()->find("input[name='forname']")
那么$results将不会被修改,您可以一次又一次地重用结果集,也许有更多知识的人可以稍微澄清一下,但从我的发现来看,基本上是这样的。
尝试简单HTML DOM解析器。
一个用PHP5+编写的HTMLDOM解析器,可以让您以非常简单的方式操作HTML!需要PHP 5+。支持无效的HTML。使用类似jQuery的选择器在HTML页面上查找标记。从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;
刮削Slashdot:
// 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);
Symfony框架具有可以解析HTML的捆绑包,您可以使用CSS样式来选择DOM,而不是使用XPath。
是的,您可以使用simple_html_dom。然而,我已经使用simple_html_dom做了很多工作,特别是在web抓取方面,发现它太脆弱了。它做了基本的工作,但无论如何我都不推荐它。
我从未使用过卷发,但我学到的是,卷发可以更有效地完成这项工作,而且更结实。
请查看此链接:使用curl刮取网站