如何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
和.class
或DIV
标签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
- 将其重命名为“select”,原因很明显
- 重命名“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类的querySelectorAll
和querySelector
方法到你的子类。
为了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,您可以使用XPath和CSSselect器来查询和迭代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'); });
有几个原因不能通过正则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);
达达!