发布日期:2018-03-26
如何在PHP中解析和处理HTML / XML?+ 查看更多
如何在PHP中解析和处理HTML / XML?
+ 查看更多
发布日期:2018-03-10 14:41
分类:PHP
浏览次数:558
如题,如何解析HTML / XML并从中提取信息?
回答:
NativeXml扩展包
我更喜欢调用NativeXml扩展包(native XML extensions)中的某一个方法来处理这个问题,因为在调用的过程中,XML会自动捆绑相关的PHP代码,通常来说这比加载第三方库服务程序来得更快。除此之外,调用的时候程序还会自动分配出所有我需要的管理权限。
DOM
相关定义:DOM扩展允许您通过PHP 5的PHP API对XML文档进行操作。它是W3C的文档对象模型核心层3的一个实现,也是一个与平台和语言无关的接口,它用于动态访问和更新程序和脚本的内容、结构和样式。
基于libxml 函数(libxml),DOM能够解析和改变存在的(破坏)HTML(超文本链接标示语言),同时它还可以进行XML路径语言查询(XPath queries)。
获取DOM的功能将会消耗一段时间,但是这种时间的等待非常值得的。而且如果您已经知道怎样使用编程语言的DOM接口,那么您就会发现由于DOM是一个与语言无关的接口,一旦你需要改变您的编程语言,您将会有许多编程语言可以实现您的需求。
如果您想知道可以如何使用DOM扩展,那么一个基本的用法示例可以在Grabbing the href attribute of an A element(在 标签 中获取的href属性)这个链接中找到。如果您只是想要知道一般的概念概述,那么您可以浏览PHP的DOM文档(DOMDocument in php)。
在StackOverflow中有许多关于怎样使用DOM扩展的问题(How to use the DOM extension has been covered extensively on StackOverflow),所以如果您选择使用DOM,您可以确保您遇到的大多数问题可以通过搜索或者浏览Stack Overflow解决。
XMLReader(XmlReader类)
相关定义:XMLReader扩展其实是一个XML pull解析器。读取器就像是光标一样在文档流上前进并且对每个节点都进行标记。
XMLReader同样基于libxml函数。我不知道如何触发HTML Parser模块,所以很有可能的是当您明确地告诉程序使用libxml的HTML Parser模块后发现使用XMLReader来解析造成HTML被破坏的程度不如使用DOM那么大。
如果您想知道可以如何使用XMLReader扩展,那么一个基本的用法示例可以在getting all values from h1 tags using php(在PHP中如何获取标签的内容)这个链接中找到。
XML Parser(XML解析器)
相关定义:这种扩展允许您创建XML解析器并且还能够为不同的XML事件定义相关的处理程序。除此之外,每个XML解析器还允许您对某些参数进行修改。
XML解析器同样基于libxml,并且它还实现了SAX风格的XML推送解析器。与DOM或SimpleXML相比,XML解析器可能是在内存管理方面更好的选择,但是相较于XMLReader实现的pull解析器,XML解析器处理起来更难。
SimpleXml(PHP的SimpleXml函数)
相关定义:SimpleXML扩展提供了非常简单和容易使用的工具集,可以将XML转换成为能够被正常的属性选择器和数组迭代器处理的对象。
当您意识到HTML是一种有效的XHTML时,SimpleXML就会成为您解析页面的一个操作选项。而如果您需要解析被破坏了的HTML,您也不用担心SimpleXML会造成您使用上的不方便,因为它会被屏蔽住。
如果您想知道可以如何使用SimpleXml函数,那么一个基本的用法示例可以在A simple program to CRUD node and node values of xml file(一个可以对节点及xml文件中节点值进行增删改查的简单程序)这个链接中找到。除此之外,在PHP手册中您可以找到更多的相关例子(lots of additional examples in the PHP Manual)。
第三方加载库(基于libxml)
如果您更喜欢使用第三方加载库,我建议使用一个基于DOM / libxml的lib(静态库),而不是使用字符串解析。
FluentDom
相关定义:FluentDOM为PHP中的DOMDocument提供了一个类似jQuery的运行速度快的XML接口。选择器是用XPath或CSS编写的(使用CSS的XPath转换)。当前的FluentDOM版本扩展了DOM实现标准接口,并且根据DOM在日常使用标准添加了相关功能。 FluentDOM可以通过Composer安装,并能够加载JSON,CSV,JsonML,RabbitFish等格式。
HtmlPageDom
相关定义:Wa72 \ HtmlPageDom是一个便于操作HTML文档的PHP库。如果您想使用它,那么您就需要操作Symfony2组件的DomCrawler(DomCrawler from Symfony2 components)遍历DOM树,并通过添加操纵HTML文档的DOM树的方法来扩展它。
phpQuery(多年未更新)
相关定义:phpQuery是一个基于以PHP5编写的jQuery JavaScript库的服务器端,可进行链接,同样也是CSS3选择器驱动的文档对象模型(DOM)的接口,并提供附加的命令行界面(CLI)。
如果您想知道更多,您可以点开这个链接:https://github.com/electrolinux/phpquery
Zend_Dom
相关定义:Zend_Dom提供了处理DOM文档和结构的工具。目前供我们使用的Zend_Dom_Query提供了一个统一的接口,并使用XPath和CSS选择器查询DOM文档。
QueryPath
相关定义:QueryPath是一个用于操作XML和HTML的PHP库。它的设计不仅服务于本地文件,还服务于Web服务和数据库资源。它实现了大部分的jQuery接口(包括CSS样式选择器),但是它很大程度上是为服务器端的使用而进行调整的一种PHP库。如果您想使用它,那么您可以通过Composer进行安装。
fDOMDocument
相关定义:fDOMDocument扩展了标准DOM用以在所有错误情况下显示异常,而不是等待PHP的警告或通知。除此之外。它还添加了各种自定义方法和快捷方式,以方便和简化DOM的使用。
sabre/xml
相关定义:saber / xml是一个包装并扩展了XMLReader类和XMLWriter类的第三方库,用以创建一个简单的“xml to object / array”映射系统和设计模式。因为它编写和读取XML都是是单向的,所以运行速度可以很快。除此之外,在大型xml文件中,它仅仅需要很小的一部分内存便可以运行。
FluidXML
相关定义:FluidXML是一个用简单流畅的API操纵XML的PHP库。它很有趣也很有效率的一点就是利用XPath和流畅的编程模式。
第三加载库方(不是基于libxml的)
基于DOM/libxml基础之上的好处是您将会有一个良好的开始,因为您是使用基于本地扩展的方式。然而,并非所有的第三方加载库都是使用的这一方式,如果您想了解这类第三方加载库,我举了一些例子在一下的文章内:
PHP Simple HTML DOM Parser(PHP中简单的HTML DOM解析器)
相关定义:
- 使用PHP5 +编写的HTML DOM解析器可让您以非常简单的方式操作HTML!
- 要求使用PHP 5+。
- 支持无效的HTML。
- 可以在HTML页面上查找与jQuery类似的选择器标签。
- 可以在一行中提取HTML内容。
我一般不推荐这个解析器。这个代码库是极不友好的,并且其解析器本身运行相当缓慢,还要求极大的内存供其使用。不是所有的jQuery选择器(如子选择器child selectors)都是合理的。使用任何基于libxml的库都应该赢过使用这个解析器。
PHP Html Parser(PHP的HTML解析器)
相关定义:PHPHtmlParser是一个简单、灵活的html解析器,允许你使用任何CSS选择器选择标签,比如使用jQuery。它的目标是协助开发工具,从而使该工具能过快速简单地丢弃掉无论是否有效的html。PHPHtmlParser原本是由sunra / php-simple-html-dom-parser支持的,但现在支持似乎已停止。因此我比较适应它从前的工作方式。
值得一提的是,我不会推荐这个解析器。因为这个解析器要求这是相当高的CPU使用率,并且运行的十分缓慢。除此之外,它还不存在能够清除已创建DOM对象的函数。特别是当您使用嵌套循环的时候将会遇到很大的麻烦。而文档本身存在的不准确和拼写的错误,自从4月16日以来就没有被修复。
Ganon
相关定义:
1. 这是一个通过使用tokenizer和HTML / XML / RSS的DOM解析器。
拥有操作元素及其属性的能力
支持无效的HTML和UTF8
2. 可以对元素执行高级的CSS3类进行查询(如jQuery -支持的命名空间)
3. HTML美化程序(例如HTML Tidy)
压缩CSS和Javascript。
进行属性排序,更改字符大小写,正确缩进等。
4. 可扩展性
使用基于当前字符/标记的回调来解析文档
操作以较小的函数分隔,以方便覆盖
5. 快速和容易操作
拥有操作元素及其属性的能力
支持无效的HTML和UTF8
2. 可以对元素执行高级的CSS3类进行查询(如jQuery -支持的命名空间)
3. HTML美化程序(例如HTML Tidy)
压缩CSS和Javascript。
进行属性排序,更改字符大小写,正确缩进等。
4. 可扩展性
使用基于当前字符/标记的回调来解析文档
操作以较小的函数分隔,以方便覆盖
5. 快速和容易操作
因为我从来没有使用过这个方法。所以并不能告诉您它是否有什么好处。
HTML 5
你可以使用上面的方式来解析HTML5,但是HTML5存在的一些标记很有可能会是您在使用的过程中产生一些奇怪的错误(there can be quirks)。所以对于HTML5我想您可以考虑使用一个专用的解析器,如:
html5lib
相关定义:一种使用Python和PHP实现的基于WHATWG HTML5规范的HTML解析器,主要用于处理我们经常使用的桌面浏览器之间的兼容性。
随着HTML5的逐渐完善,我想我们可能会看到更多的专用解析器。除此之外,如果您想了解得更多,我认为有一篇位于W3的标题为How-To for html 5 parsing(怎样对HTML5进行解析)的博客文章很值得看一看。
WebServices(网页服务)
如果你不想使用PHP进行编程,你也可以使用Web services。虽然我认为很少有实用的相关服务器,但是您也不必较真,这只是我个人在使用相关用例时的想法而已。
YQL(雅虎查询语言)
相关定义:YQL Web服务使应用程序能够查询,过滤和合并Internet上不同来源的数据。 YQL语句有类似SQL的语法,任何有过数据库开发的人员应该都会对它有熟悉感。
ScraperWiki(数据科学维基百科)
相关定义:ScraperWiki的外部接口允许您以您希望在Web或自己的应用程序中使用的形式提取数据。除此之外,您还可以提取任何有关scraper状态(一个 Google Chrome 扩展用于从网页获取数据并存到电子表格)的信息。
正则表达式
最后我要推荐的是使用正则表达式(regular expressions)从HTML提取数据。一般来说,我并不建议使用HTML上的正则表达式。
大多数你能在网上能够找到匹配标记的片段都是零散的。在大多数情况下,它们只工作在一个非常特定的HTML。哪怕只是一个小小的标记被更改,例如在某处添加空格,或者添加更改标记中的属性,都可能会导致正则表达式由于未正确写入而失败。在HTML上使用正则表达式之前,你应该想清楚知道你要做什么。
HTML解析器已经能够很清楚地分析出HTML的语法规则。而您写的每个新的正则表达式必须和您先前写的正则表达式之间存在衔接关系。确实,正则表达式在某些情况下真的是一种很好的选择,但它的能力能不能被很好的发挥实际上取决于您的使用用例。
您可以编写更可靠的解析器(can write more reliable parsers),但是使用正则表达式编写一个完整可靠的自定义解析器其实是在浪费时间,因为上述各种有效的资源库已经存在,并做了更好的工作。
另外您还可以参阅Parsing Html The Cthulhu Way(用Cthulhu方式解析Html)。
书本推荐
如果您认为您可以花一些费用以看到更多资料,您可以看下面这个文档
PHP Architect's Guide to Webscraping with PHP (PHP架构师使用PHP知道使用Webscraping的指南)
声明下,我并不是PHP架构师,也不是这本书的作者。