如何parsing和处理PHP中的HTML / XML?

如何parsingHTML / XML并从中提取信息?

原生XML扩展

我更喜欢使用原生XML扩展之一,因为他们与PHP捆绑在一起,通常比所有的第三方库更快,给我所有的控制我需要通过标记。

DOM

DOM扩展允许您使用PHP 5通过DOM API对XML文档进行操作。它是W3C的文档对象模型Core Level 3的实现,它是一个平台和语言无关的接口,允许程序和脚本dynamic访问和更新文件的内容,结构和风格。

DOM能够parsing和修改真实世界(损坏)的HTML,并且可以执行XPath查询 。 它基于libxml 。

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

一个基本的用法示例可以在抓取A元素的href属性中find,一般概念概述可以在DOMDocument中find

如何使用DOM扩展已经在StackOverflow中得到了广泛的介绍 ,所以如果你select使用它,你可以确定你遇到的大部分问题都可以通过search/浏览Stack Overflow来解决。

XMLReader的

XMLReader扩展是一个XML拉parsing器。 阅读器充当文档stream上的光标,并在途中的每个节点处停止。

像XML一样,XMLReader基于libxml。 我不知道如何触发HTMLparsing器模块,因此使用XMLReaderparsing断开的HTML的可能性比使用DOM明显地告诉它使用libxml的HTMLparsing器模块的可能性要低。

一个基本的用法示例可以在使用php获取来自h1标签的所有值

XMLparsing器

这个扩展允许您创buildXMLparsing器,然后为不同的XML事件定义处理程序。 每个XMLparsing器也有一些可以调整的参数。

XMLparsing器库也基于libxml,并实现了SAX风格的XML推送parsing器。 内存pipe理可能比DOM或SimpleXML更好,但是比使用XMLReader实现的pullparsing器更难。

SimpleXML的

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

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

一个基本的用法示例可以在一个简单的程序中findxml文件的CRUD节点和节点值, 在PHP手册中还有大量的附加示例 。


第三方库(基于libxml)

如果你更喜欢使用第三方库,我build议使用一个实际使用DOM / libxml而不是stringparsing的库。

FluentDom

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

HtmlPageDom

Wa72 \ HtmlPageDom是一个PHP库,可以轻松处理HTML文档。它需要Symfony2组件中的DomCrawler遍历DOM树,并通过添加操作HTML文档DOM树的方法来扩展它。

phpQuery (未更新多年)

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

另请参阅: https : //github.com/electrolinux/phpquery

Zend_Dom

Zend_Dom提供了用于处理DOM文档和结构的工具。 目前,我们提供了Zend_Dom_Query,它提供了一个统一的接口,用于使用XPath和CSSselect器来查询DOM文档。

的QueryPath

QueryPath是一个用于处理XML和HTML的PHP​​库。 它被devise成不仅与本地文件一起工作,而且还与Web服务和数据库资源一起工作。 它实现了大部分的jQuery接口(包括CSS风格的select器),但是对服务器端的使用进行了严格的调整。 可以通过Composer进行安装。

fDOMDocument

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

军刀/ XML

saber / xml是一个包装和扩展XMLReader和XMLWriter类的库,以创build一个简单的“xml to object / array”映射系统和devise模式。 写入和读取XML是单向的,因此可以是快速的并且需要大的xml文件的低内存。

FluidXML

FluidXML是一个用简洁而stream畅的API操纵XML的PHP​​库。 它利用了XPath和stream畅的编程模式,变得有趣而有效。


第三方(不是基于libxml的)

build立在DOM / libxml上的好处是你可以获得很好的性能,因为你基于本地扩展。 然而,并不是所有的第三方库都沿着这条路线走下去。 其中一些列在下面

PHP简单的HTML DOMparsing器

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

我通常不推荐这个parsing器。 代码库是可怕的,parsing器本身是比较慢,内存饿了。 并非所有的jQueryselect器(如子select器 )都是可能的。 任何基于libxml的库应该比这个容易。

PHP的HTMLparsing器

PHPHtmlParser是一个简单,灵活的HTMLparsing器,它允许你使用任何CSSselect器,如jQueryselect标签。 我们的目标是协助开发工具,这需要一个快速,简单的方法来删除HTML,无论是否有效! 这个项目最初由sunra / php-simple-html-dom-parser支持,但支持似乎已经停止了,所以这个项目是我对他以前的工作的改编。

再次,我不会推荐这个parsing器。 CPU占用率高,速度慢。 也没有函数来清除所创build的DOM对象的内存。 这些问题特别是嵌套循环。 文件本身是不准确的,拼写错误,自16年4月14日以来没有答复修复。

加农

  • 通用标记器和HTML / XML / RSS DOMparsing器
    • 能够操纵元素及其属性
    • 支持无效的HTML和UTF8
  • 可以对元素执行高级CSS3类查询(比如jQuery – 支持的命名空间)
  • 一个HTML美化(如HTML Tidy)
    • 缩小CSS和Javascript
    • sorting属性,更改字符大小写,正确缩进等
  • 扩展
    • 使用基于当前字符/标记的callback来parsing文档
    • 操作以较小的函数分隔,以便于覆盖
  • 快速和容易

从未使用过。 不知道是否有好处。


HTML 5

您可以使用上面的parsingHTML5,但是由于HTML5允许的标记,可能会出现怪癖 。 所以对于HTML5你想考虑使用一个专用的parsing器,比如

html5lib

基于WHATWG HTML5规范的HTMLparsing器的Python和PHP实现,用于与主要桌面Web浏览器的最大兼容性。

一旦HTML5完成,我们可能会看到更多的专用parsing器。 也有一个W3的标题为How to To HTML 5parsing ,这是值得一试的博客。


网页服务

如果你不喜欢编程PHP,你也可以使用Web服务。 一般来说,我发现这些function很less,但这只是我和我的用例。

YQL

YQL Web服务使应用程序能够查询,过滤和组合来自互联网上不同来源的数据。 YQL语句具有类似于SQL的语法,任何具有数据库经验的开发人员都会熟悉。

ScraperWiki 。

ScraperWiki的外部接口允许您以networking或自己的应用程序的forms提取数据。 您也可以提取有关任何刮板状态的信息。


正则expression式

最后,也是最不推荐的 ,你可以用正则expression式从HTML中提取数据。 一般情况下在HTML上使用正则expression式是不鼓励的。

大部分你在网上find的匹配标记的片段都很脆弱。 在大多数情况下,他们只为一个非常特殊的HTML工作。 微小的标记变化,比如在某个地方添加空格,或者在标签中添加或者改变属性,会导致正则expression式在不正确的写入时失败。 在HTML上使用正则expression式之前,您应该知道自己在做什么。

HTMLparsing器已经知道HTML的语法规则。 正则expression式必须教你每个新的正则expression式。 在某些情况下,正则expression式很好,但是这取决于你的用例。

您可以编写更可靠的parsing器 ,但是使用正则expression式编写完整且可靠的定制parsing器会浪费时间,因为前面提到的库已经存在,并且做得更好。

另请参阅parsingHtml The Cthulhu Way


图书

如果你想花一些钱,看看

  • PHP架构师使用PHP进行Web浏览的指南

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

尝试简单的HTML DOMparsing器

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

例子:

如何获取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); 

只需使用DOMDocument-> loadHTML()并完成它。 libxml的HTMLparsingalgorithm相当好,速度很快,与stream行的观点相反,它不会歪曲格式错误的HTML。

为什么你不应该使用正则expression式?

首先,一个常见的误称:正则expression式不是用来parsing HTML的。 正则expression式可以提取数据。 提取是他们的目的。 正则expression式提取超过正确的SGML工具包或基线XMLparsing器的主要缺点是它们的语法工作量和不同的可靠性。

考虑做一个可靠的HTML提取正则expression式:

 <a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title [\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+? 

是一种简单的phpQuery或QueryPath等效方式:

 $div->find(".stationcool a")->attr("title"); 

然而,有特定的用例可以帮助他们。

  • 许多DOM遍历前端不会显示HTML注释<!-- ,但有时它们是提取更有用的锚点。 特别是伪HTML变体<$var>或SGML残基很容易被正则expression式驯服。
  • 通常,正则expression式可以节省后期处理。 但是,HTML实体通常需要手动处理。
  • 最后,对于像提取<img src = url这样的非常简单的任务 ,它们实际上是一个可能的工具。 与SGML / XMLparsing器相比,速度优势主要体现在这些非常基本的提取过程中。

有时甚至build议使用正则expression式/<!--CONTENT-->(.+?)<!--END-->/预先提取HTML片段,并使用更简单的HTMLparsing器前端处理剩余的部分。

注意:我实际上有这个应用程序 ,我使用XMLparsing和正则expression式交替。 就在上个星期,PyQueryparsing破解了,正则expression式仍然有效。 是奇怪的,我不能自己解释。 但事情发生了。
所以,请不要将真实世界的考虑因素投下来,只是因为它不符合regex = evil meme。 但是,我们也不要投票太多。 这只是这个话题的一个旁注。

phpQuery和QueryPath在复制stream畅的jQuery API方面非常相似。 这也是为什么他们是在PHP中正确parsingHTML的两种最简单的方法。

QueryPath的示例

基本上你首先从一个HTMLstring创build一个可查询的DOM树:

  $qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL 

生成的对象包含HTML文档的完整树形表示。 它可以使用DOM方法遍历。 但常用的方法是像使用jQuery一样使用CSSselect器:

  $qp->find("div.classname")->children()->...; foreach ($qp->find("p img") as $img) { print qp($img)->attr("src"); } 

大多数情况下,您希望使用简单的#id.classDIV标签select器来执行->find() 。 但是你也可以使用XPath语句,有时候这个语句更快。 另外,像->children()->text() ,特别是->attr()这样的典型jQuery方法可以简化提取正确的HTML代码片段。 (已经有他们的SGML实体解码。)

  $qp->xpath("//div/p[1]"); // get first paragraph in a div 

QueryPath还允许向stream中->append新的标签( ->append ),并稍后输出和美化已更新的文档( ->writeHTML )。 它不仅可以parsing格式不正确的HTML,而且可以parsing各种XML方言(带有命名空间),甚至可以从HTML微格式(XFN,vCard)中提取数据。

  $qp->find("a[target=_blank]")->toggleClass("usability-blunder"); 

phpQuery或QueryPath?

通常QueryPath更适合于处理文档。 虽然phpQuery也实现了一些伪AJAX方法(只是HTTP请求)更接近jQuery。 据说phpQuery通常比QueryPath更快(因为整体function较less)。

有关差异的更多信息,请参阅tagbyte.org上的wayback机器的比较 。 (原始资料不见了,所以这里有一个互联网档案的链接。是的,你仍然可以find遗失的网页,人。)

这里有一个全面的QueryPath介绍 。

优点

  • 简单和可靠
  • 简单易用的替代品->find("a img, a object, div a")
  • 适当的数据消除(与正则expression式相比)

简单的HTML DOM是一个伟大的开源parsing器:

simplehtmldom.sourceforge

它以面向对象的方式对待DOM元素,新的迭代对不兼容的代码有很多的覆盖。 还有一些很棒的function就像你在JavaScript中看到的那样,比如“find”function,它将返回标签名称元素的所有实例。

我已经在很多工具中使用了这个工具,在很多不同types的网页上testing它,我认为它工作的很好。

我在这里没有提到的一个通用方法是通过Tidy运行HTML,它可以被设置为吐出保证有效的XHTML。 那么你可以使用任何旧的XML库。

但是对于你的具体问题,你应该看看这个项目: http : //fivefilters.org/content-only/ – 这是一个Readabilityalgorithm的修改版本,它被devise为只提取文本内容(不是头文件和页脚)从一个页面。

对于1a和2:我会投票支持新的Symfony Componet类DOMCrawler( DomCrawler )。 这个类允许类似于CSSselect器的查询。 看看这个演示文稿中的真实世界的例子: symfony2世界的新闻 。

该组件被devise为独立工作,并且可以在没有Symfony的情况下使用。

唯一的缺点是只能使用PHP 5.3或更新版本。

顺便说一下,这通常被称为屏幕抓取 。 我用这个库是简单的HTML Domparsing器 。

之前我们已经为我们的需求创build了不less爬虫。 在一天结束的时候,通常是简单的正则expression式来做最好的事情。 虽然上面列出的库对于创build它们的原因很有好处,但是如果您知道要查找的内容,则正则expression式是更安全的方法,因为您也可以处理无效的HTML / XHTML结构,如果加载通过大多数parsing器。

我推荐PHP简单的HTML DOMparsing器 。

它真的有很好的function,如:

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

这听起来像W3C XPath技术的一个很好的任务描述。 像“嵌套在<foo><bar><baz> elements中的img标签中返回所有href属性”这样的查询很容易。 不是一个PHP的BUFF,我不能告诉你什么forms的XPath可用。 如果您可以调用外部程序来处理HTML文件,您应该可以使用命令行版本的XPath。 有关快速介绍,请参阅http://en.wikipedia.org/wiki/XPath

SimpleHtmlDom的第三方替代品,使用DOM而不是string分析: phpQuery , Zend_Dom , QueryPath和FluentDom 。

是的,你可以使用simple_html_dom来达到目的。 然而,我对simple_html_dom工作了很多,特别是对于networking报废,并且发现它太脆弱了。 它做的基本工作,但我不会推荐它。

我从来没有用curl的目的,但我所学到的是,curl可以更有效地完成这项工作,更坚实。

请检查这个链接: scraping-websites-curl

QueryPath是好的,但是如果你没有意识到“跟踪状态”的原因,要小心,这可能意味着你浪费了大量的debugging时间来试图找出发生了什么,代码不工作的原因。

这意味着结果集上的每个调用都会修改对象中的结果集,它不像jquery中那样可链接,其中每个链接都是一个新集,您有一个单独的集合,它是查询的结果,每个函数调用都会修改那一套。

为了得到类似jquery的行为,你需要在进行过滤/修改之前进行分支操作,这意味着它会更仔细地反映jquery中发生的事情。

 $results = qp("div p"); $forename = $results->find("input[name='forename']"); 

$results现在包含input[name='forename']的结果集input[name='forename']不是原来的查询"div p"这使我绊倒了很多,我发现是QueryPath跟踪filter和发现和一切修改你的结果和存储他们在对象。 你需要这样做

 $forename = $results->branch()->find("input[name='forname']") 

那么$results将不会被修改,您可以一次又一次地重复使用结果集,也许有更多知识的人可以稍微澄清一点,但基本上就是我所发现的。

我写了一个可以轻松处理GB文件的通用XMLparsing器。 它基于XMLReader,使用起来非常简单:

 $source = new XmlExtractor("path/to/tag", "/path/to/file.xml"); foreach ($source as $tag) { echo $tag->field1; echo $tag->field2->subfield1; } 

这里是github回购: XmlExtractor

对于HTML5 ,html5 lib已经放弃了很多年了。 最近更新和维护logging中唯一可以find的HTML5库是html5-php ,它在一周前刚刚被引入beta 1.0。

您可以尝试使用HTML Tidy之类的东西来清理任何“破损”的HTML,然后将HTML转换为XHTML,然后使用XMLparsing器进行parsing。

我创build了一个名为PHPPowertools / DOM-Query的库,它可以像使用jQuery一样抓取HTML5和XML文档。

在引擎盖下,它使用symfony / DomCrawler将CSSselect器转换为XPathselect器。 它始终使用相同的DomDocument,即使传递一个对象到另一个对象,以确保体面的performance。


使用示例:

 namespace PowerTools; // Get file content $htmlcode = file_get_contents('https://github.com'); // Define your DOMCrawler based on file string $H = new DOM_Query($htmlcode); // Define your DOMCrawler based on an existing DOM_Query instance $H = new DOM_Query($H->select('body')); // Passing a string (CSS selector) $s = $H->select('div.foo'); // Passing an element object (DOM Element) $s = $H->select($documentBody); // Passing a DOM Query object $s = $H->select( $H->select('p + p')); // Select the body tag $body = $H->select('body'); // Combine different classes as one selector to get all site blocks $siteblocks = $body->select('.site-header, .masthead, .site-body, .site-footer'); // Nest your methods just like you would with jQuery $siteblocks->select('button')->add('span')->addClass('icon icon-printer'); // Use a lambda function to set the text of all site blocks $siteblocks->text(function( $i, $val) { return $i . " - " . $val->attr('class'); }); // Append the following HTML to all site blocks $siteblocks->append('<div class="site-center"></div>'); // Use a descendant selector to select the site's footer $sitefooter = $body->select('.site-footer > .site-center'); // Set some attributes for the site's footer $sitefooter->attr(array('id' => 'aweeesome', 'data-val' => 'see')); // Use a lambda function to set the attributes of all site blocks $siteblocks->attr('data-val', function( $i, $val) { return $i . " - " . $val->attr('class') . " - photo by Kelly Clark"; }); // Select the parent of the site's footer $sitefooterparent = $sitefooter->parent(); // Remove the class of all i-tags within the site's footer's parent $sitefooterparent->select('i')->removeAttr('class'); // Wrap the site's footer within two nex selectors $sitefooter->wrap('<section><div class="footer-wrapper"></div></section>'); [...] 

支持的方法:

  • [x] $ (1)
  • [x] $ .parseHTML
  • [x] $ .parseXML
  • [x] $ .parseJSON
  • [x] $ selection.add
  • [x] $ selection.addClass
  • [x] $ selection.after
  • [x] $ selection.append
  • [x] $ selection.attr
  • [x] $ selection.before
  • [x] $ selection.children
  • [x] $ selection.closest
  • [x] $ selection.contents
  • [x] $ selection.detach
  • [x] $ selection.each
  • [x] $ selection.eq
  • [x] $ selection.empty (2)
  • [x] $ selection.find
  • [x] $ selection.first
  • [x] $ selection.get
  • [x] $ selection.insertAfter
  • [x] $ selection.insertBefore
  • [x] $ selection.last
  • [x] $ selection.parent
  • [x] $ selection.parents
  • [x] $ selection.remove
  • [x] $ selection.removeAttr
  • [x] $ selection.removeClass
  • [x] $ selection.text
  • [x] $ selection.wrap

  1. 将其重命名为“select”,原因很明显
  2. 重命名“void”,因为“empty”是PHP中的保留字

注意 :

该库还包含用于PSR-0兼容库的零configuration自动加载器。 所包含的示例应该在没有任何其他configuration的情况下开箱即用。 另外,你可以使用它与composer php。

另一个可以尝试的select是QueryPath 。 它的灵感来自jQuery,但在PHP的服务器上,并在Drupal中使用 。

处理其中大部分已经提到的HTML / XML DOM有很多方法。 因此,我不会试图自己列出。

我只想补充一点,我个人更喜欢使用DOM扩展,为什么:

  • iit最佳地利用底层C代码的性能优势
  • 这是OO的PHP(并允许我inheritance它)
  • 这是相当低的水平(这使我可以使用它作为一个非臃肿的基础,更先进的行为)
  • 它提供对DOM每个部分的访问(与例如SimpleXml不同,它忽略了一些较less的已知XML特性)
  • 它具有用于DOM爬行的语法,类似于原生Javascript中使用的语法。

虽然我错过了为DOMDocument使用CSSselect器的能力,但是有一个相当简单和方便的方法来添加这个特性:子类化DOMDocument并添加JS类的querySelectorAllquerySelector方法到你的子类。

为了parsingselect器,我build议使用Symfony框架中非常简约的CssSelector组件 。 该组件只是将CSSselect器转换为XPathselect器,然后可以将它们馈送到DOMXpath以检索相应的DOMXpath列表。

然后,您可以使用这个(仍然非常低的水平)子类作为更高层次的基础,用于例如。 parsing特定types的XML或添加更多类似jQuery的行为。

下面的代码直接出来我的DOM查询库,并使用我所描述的技术。

对于HTMLparsing:

 namespace PowerTools; use \Symfony\Component\CssSelector\CssSelector as CssSelector; class DOM_Document extends \DOMDocument { public function __construct($data = false, $doctype = 'html', $encoding = 'UTF-8', $version = '1.0') { parent::__construct($version, $encoding); if ($doctype && $doctype === 'html') { @$this->loadHTML($data); } else { @$this->loadXML($data); } } public function querySelectorAll($selector, $contextnode = null) { if (isset($this->doctype->name) && $this->doctype->name == 'html') { CssSelector::enableHtmlExtension(); } else { CssSelector::disableHtmlExtension(); } $xpath = new \DOMXpath($this); return $xpath->query(CssSelector::toXPath($selector, 'descendant::'), $contextnode); } [...] public function loadHTMLFile($filename, $options = 0) { $this->loadHTML(file_get_contents($filename), $options); } public function loadHTML($source, $options = 0) { if ($source && $source != '') { $data = trim($source); $html5 = new HTML5(array('targetDocument' => $this, 'disableHtmlNsInDom' => true)); $data_start = mb_substr($data, 0, 10); if (strpos($data_start, '<!DOCTYPE ') === 0 || strpos($data_start, '<html>') === 0) { $html5->loadHTML($data); } else { @$this->loadHTML('<!DOCTYPE html><html><head><meta charset="' . $encoding . '" /></head><body></body></html>'); $t = $html5->loadHTMLFragment($data); $docbody = $this->getElementsByTagName('body')->item(0); while ($t->hasChildNodes()) { $docbody->appendChild($t->firstChild); } } } } [...] } 

另请参阅由Symfony的创build者Fabien Potencier 用CSSselect器parsingXML文档,他决定为Symfony创buildCssSelector组件,以及如何使用它。

XML_HTMLSax相当稳定 – 即使不再维护。 另一个select是通过Html Tidy来pipe理HTML ,然后用标准的XML工具parsing它。

Symfony框架包含可以parsingHTML的bundle,您可以使用CSS样式来selectDOM,而不是使用XPath 。

高级Html Dom是一个简单的HTML DOMreplace,提供了相同的接口,但它是基于DOM的,这意味着没有任何关联的内存问题发生。

它也有完整的CSS支持,包括jQuery扩展。

使用FluidXML,您可以使用XPathCSSselect器来查询和迭代XML。

 $doc = fluidxml('<html>...</html>'); $title = $doc->query('//head/title')[0]->nodeValue; $doc->query('//body/p', 'div.active', '#bgId') ->each(function($i, $node) { // $node is a DOMNode. $tag = $node->nodeName; $text = $node->nodeValue; $class = $node->getAttribute('class'); }); 

https://github.com/servo-php/fluidxml

有几个原因不能通过正则expression式parsingHTML。 但是,如果您完全控制将生成的HTML,那么您可以使用简单的正则expression式来完成。

上面是一个通过正则expression式parsingHTML的函数。 请注意,这个函数非常敏感,并且要求HTML服从一定的规则,但是在很多情况下它运行得非常好。 如果你想要一个简单的parsing器,并且不想安装库,请给这个镜头:

 function array_combine_($keys, $values) { $result = array(); foreach ($keys as $i => $k) { $result[$k][] = $values[$i]; } array_walk($result, create_function('&$v', '$v = (count($v) == 1)? array_pop($v): $v;')); return $result; } function extract_data($str) { return (is_array($str)) ? array_map('extract_data', $str) : ((!preg_match_all('#<([A-Za-z0-9_]*)[^>]*>(.*?)</\1>#s', $str, $matches)) ? $str : array_map(('extract_data'), array_combine_($matches[1], $matches[2]))); } print_r(extract_data(file_get_contents("http://www.google.com/"))); 

来自XML的JSON和数组分为三行:

 $xml = simplexml_load_string($xml_string); $json = json_encode($xml); $array = json_decode($json,TRUE); 

达达!