如何解析HTML / XML并从中提取信息?
如何解析HTML / XML并从中提取信息?
我更喜欢使用其中一个 原生XML扩展 因为它们与PHP捆绑在一起,通常比所有第三方库更快,并且在标记上给我所需的所有控制权。
DOM扩展允许您通过PHP API使用PHP 5对XML文档进行操作。它是W3C的文档对象模型核心级别3的实现,这是一个平台和语言中立的接口,允许程序和脚本动态访问和更新文件的内容,结构和风格。
DOM能够解析和修改现实世界(破碎)的HTML,它可以做到 XPath查询。它基于 的libxml。
使用DOM需要一些时间才能提高效率,但这个时间非常值得IMO。由于DOM是一个与语言无关的接口,因此您可以找到多种语言的实现,因此如果您需要更改编程语言,那么您很可能已经知道如何使用该语言的DOM API。
可以在中找到基本用法示例 抓取A元素的href属性 一般的概念概述可以在 php中的DOMDocument
StackOverflow上广泛介绍了如何使用DOM扩展,因此,如果您选择使用它,您可以确定您遇到的大多数问题都可以通过搜索/浏览Stack Overflow来解决。
XMLReader扩展是一个XML pull解析器。读取器在文档流上作为光标前进,并在途中停在每个节点上。
与DOM一样,XMLReader基于libxml。我不知道如何触发HTML Parser模块,因此使用XMLReader解析损坏的HTML的可能性可能不如使用DOM,因为您可以明确告诉它使用libxml的HTML Parser Module。
可以在以下位置找到基本用法示例 使用php从h1标签获取所有值
此扩展允许您创建XML解析器,然后为不同的XML事件定义处理程序。每个XML解析器还有一些您可以调整的参数。
XML Parser库也基于libxml,并实现了一个 SAX style XML push parser。它可能是比DOM或SimpleXML更好的内存管理选择,但是比XMLReader实现的pull解析器更难以使用。
SimpleXML扩展提供了一个非常简单且易于使用的工具集,用于将XML转换为可以使用普通属性选择器和数组迭代器处理的对象。
当您知道HTML是有效的XHTML时,SimpleXML是一个选项。如果你需要解析破碎的HTML,甚至不要考虑SimpleXml,因为它会窒息。
可以在以下位置找到基本用法示例 一个简单的CRUD节点程序和xml文件的节点值 并且有 PHP手册中的许多其他示例。
如果您更喜欢使用第三方库,我建议使用实际使用的库 DOM/的libxml 在下面而不是字符串解析。
FluentDOM为PHP中的DOMDocument提供了类似jQuery的流畅XML接口。选择器是用XPath或CSS编写的(使用CSS到XPath转换器)。当前版本扩展了DOM实现标准接口并添加了DOM Living Standard的功能。 FluentDOM可以加载JSON,CSV,JsonML,RabbitFish等格式。可以通过Composer安装。
Wa72 \ HtmlPageDom`是一个易于操作HTML的PHP库 文件使用它需要 来自Symfony2的DomCrawler 组件 穿越 DOM树并通过添加操作DOM的方法来扩展它 HTML文档树。
phpQuery是一个服务器端,可链接,CSS3选择器驱动的文档对象模型(DOM)API,基于用PHP5编写的jQuery JavaScript库,并提供额外的命令行界面(CLI)。
另见: https://github.com/electrolinux/phpquery
Zend_Dom提供了处理DOM文档和结构的工具。目前,我们提供Zend_Dom_Query,它提供了一个统一的界面,用于使用XPath和CSS选择器查询DOM文档。
QueryPath是一个用于操作XML和HTML的PHP库。它不仅适用于本地文件,还适用于Web服务和数据库资源。它实现了大部分jQuery接口(包括CSS样式选择器),但它经过大量调整以供服务器端使用。可以通过Composer安装。
fDOMDocument扩展了标准DOM,以便在所有错误情况下使用异常,而不是PHP警告或通知。为方便起见,他们还添加了各种自定义方法和快捷方式,并简化了DOM的使用。
saber / xml是一个包装和扩展XMLReader和XMLWriter类的库,用于创建一个简单的“xml到对象/数组”映射系统和设计模式。编写和读取XML是单遍的,因此可以快速并且需要大型xml文件的低内存。
FluidXML是一个PHP库,用于通过简洁流畅的API来操作XML。 它利用XPath和流畅的编程模式,既有趣又有效。
构建DOM / libxml的好处是,您可以获得良好的开箱即用性能,因为您基于本机扩展。但是,并非所有第三方库都沿着这条路线行进。其中一些列在下面
- 用PHP5 +编写的HTML DOM解析器允许您以非常简单的方式操作HTML!
- 需要PHP 5+。
- 支持无效的HTML。
- 使用选择器在HTML页面上查找标签,就像jQuery一样。
- 从一行中提取HTML中的内容。
我一般不推荐这个解析器。代码库很糟糕,解析器本身很慢而且内存很耗。并非所有jQuery选择器(例如 儿童选择器)是可能的。任何基于libxml的库都应该比这更容易。
PHPHtmlParser是一个简单,灵活的html解析器,允许您使用任何css选择器(如jQuery)选择标签。目标是协助开发需要快速,简单的方法来废弃html的工具,无论它是否有效!这个项目是由sunra / php-simple-html-dom-parser原创支持的,但支持似乎已经停止,所以这个项目是我对他以前工作的改编。
同样,我不推荐这个解析器。 CPU使用率很高,速度相当慢。还没有清除已创建DOM对象的内存的功能。这些问题尤其适用于嵌套循环。文档本身不准确且拼写错误,自4月14日以来没有对修复的响应。
- 通用标记器和HTML / XML / RSS DOM解析器
- 能够操纵元素及其属性
- 支持无效的HTML和UTF8
- 可以对元素执行类似CSS3的高级查询(比如jQuery - 支持的命名空间)
- HTML美化器(如HTML Tidy)
- 缩小CSS和Javascript
- 排序属性,更改字符大小写,更正缩进等。
- 扩展
- 使用基于当前字符/标记的回调解析文档
- 操作以较小的功能分隔,以便轻松覆盖
- 快速而简单
从未使用过它。不知道它是否有用。
您可以使用上面的解析HTML5,但是 可能有怪癖 由于HTML5允许的标记。因此,对于HTML5,您要考虑使用专用解析器,例如
基于WHATWG HTML5规范的HTML解析器的Python和PHP实现,可最大程度地兼容主要桌面Web浏览器。
HTML5最终确定后,我们可能会看到更多专用解析器。还有一个由W3标题为的博客文章 如何进行html 5解析 这值得一试。
如果您不想编写PHP,也可以使用Web服务。一般来说,我发现这些实用程序的效用很小,但这只是我和我的用例。
YQL Web服务使应用程序能够在Internet上查询,过滤和组合来自不同来源的数据。 YQL语句具有类似SQL的语法,对于具有数据库经验的任何开发人员来说都很熟悉。
ScraperWiki的外部界面允许您以您希望在Web或您自己的应用程序中使用的形式提取数据。您还可以提取有关任何刮刀状态的信息。
最后和 最不推荐的,您可以从HTML中提取数据 常用表达。通常,不鼓励在HTML上使用正则表达式。
您在网上找到的大多数与标记相匹配的片段都很脆弱。在大多数情况下,它们只适用于非常特殊的HTML。微小的标记更改,例如在某处添加空格,或添加或更改标记中的属性,可能会导致RegEx在未正确编写时失败。在HTML上使用RegEx之前,您应该知道自己在做什么。
HTML解析器已经知道HTML的语法规则。必须为您编写的每个新RegEx讲授正则表达式。 RegEx在某些情况下很好,但它实际上取决于您的用例。
您 可以编写更可靠的解析器但是写一个 完整可靠 具有正则表达式的自定义解析器在上述库已经存在并且在此方面做得更好时浪费时间。
另见 解析Html克苏鲁方式
如果你想花一些钱,看看吧
我不隶属于PHP Architect或作者。
我更喜欢使用其中一个 原生XML扩展 因为它们与PHP捆绑在一起,通常比所有第三方库更快,并且在标记上给我所需的所有控制权。
DOM扩展允许您通过PHP API使用PHP 5对XML文档进行操作。它是W3C的文档对象模型核心级别3的实现,这是一个平台和语言中立的接口,允许程序和脚本动态访问和更新文件的内容,结构和风格。
DOM能够解析和修改现实世界(破碎)的HTML,它可以做到 XPath查询。它基于 的libxml。
使用DOM需要一些时间才能提高效率,但这个时间非常值得IMO。由于DOM是一个与语言无关的接口,因此您可以找到多种语言的实现,因此如果您需要更改编程语言,那么您很可能已经知道如何使用该语言的DOM API。
可以在中找到基本用法示例 抓取A元素的href属性 一般的概念概述可以在 php中的DOMDocument
StackOverflow上广泛介绍了如何使用DOM扩展,因此,如果您选择使用它,您可以确定您遇到的大多数问题都可以通过搜索/浏览Stack Overflow来解决。
XMLReader扩展是一个XML pull解析器。读取器在文档流上作为光标前进,并在途中停在每个节点上。
与DOM一样,XMLReader基于libxml。我不知道如何触发HTML Parser模块,因此使用XMLReader解析损坏的HTML的可能性可能不如使用DOM,因为您可以明确告诉它使用libxml的HTML Parser Module。
可以在以下位置找到基本用法示例 使用php从h1标签获取所有值
此扩展允许您创建XML解析器,然后为不同的XML事件定义处理程序。每个XML解析器还有一些您可以调整的参数。
XML Parser库也基于libxml,并实现了一个 SAX style XML push parser。它可能是比DOM或SimpleXML更好的内存管理选择,但是比XMLReader实现的pull解析器更难以使用。
SimpleXML扩展提供了一个非常简单且易于使用的工具集,用于将XML转换为可以使用普通属性选择器和数组迭代器处理的对象。
当您知道HTML是有效的XHTML时,SimpleXML是一个选项。如果你需要解析破碎的HTML,甚至不要考虑SimpleXml,因为它会窒息。
可以在以下位置找到基本用法示例 一个简单的CRUD节点程序和xml文件的节点值 并且有 PHP手册中的许多其他示例。
如果您更喜欢使用第三方库,我建议使用实际使用的库 DOM/的libxml 在下面而不是字符串解析。
FluentDOM为PHP中的DOMDocument提供了类似jQuery的流畅XML接口。选择器是用XPath或CSS编写的(使用CSS到XPath转换器)。当前版本扩展了DOM实现标准接口并添加了DOM Living Standard的功能。 FluentDOM可以加载JSON,CSV,JsonML,RabbitFish等格式。可以通过Composer安装。
Wa72 \ HtmlPageDom`是一个易于操作HTML的PHP库 文件使用它需要 来自Symfony2的DomCrawler 组件 穿越 DOM树并通过添加操作DOM的方法来扩展它 HTML文档树。
phpQuery是一个服务器端,可链接,CSS3选择器驱动的文档对象模型(DOM)API,基于用PHP5编写的jQuery JavaScript库,并提供额外的命令行界面(CLI)。
另见: https://github.com/electrolinux/phpquery
Zend_Dom提供了处理DOM文档和结构的工具。目前,我们提供Zend_Dom_Query,它提供了一个统一的界面,用于使用XPath和CSS选择器查询DOM文档。
QueryPath是一个用于操作XML和HTML的PHP库。它不仅适用于本地文件,还适用于Web服务和数据库资源。它实现了大部分jQuery接口(包括CSS样式选择器),但它经过大量调整以供服务器端使用。可以通过Composer安装。
fDOMDocument扩展了标准DOM,以便在所有错误情况下使用异常,而不是PHP警告或通知。为方便起见,他们还添加了各种自定义方法和快捷方式,并简化了DOM的使用。
saber / xml是一个包装和扩展XMLReader和XMLWriter类的库,用于创建一个简单的“xml到对象/数组”映射系统和设计模式。编写和读取XML是单遍的,因此可以快速并且需要大型xml文件的低内存。
FluidXML是一个PHP库,用于通过简洁流畅的API来操作XML。 它利用XPath和流畅的编程模式,既有趣又有效。
构建DOM / libxml的好处是,您可以获得良好的开箱即用性能,因为您基于本机扩展。但是,并非所有第三方库都沿着这条路线行进。其中一些列在下面
- 用PHP5 +编写的HTML DOM解析器允许您以非常简单的方式操作HTML!
- 需要PHP 5+。
- 支持无效的HTML。
- 使用选择器在HTML页面上查找标签,就像jQuery一样。
- 从一行中提取HTML中的内容。
我一般不推荐这个解析器。代码库很糟糕,解析器本身很慢而且内存很耗。并非所有jQuery选择器(例如 儿童选择器)是可能的。任何基于libxml的库都应该比这更容易。
PHPHtmlParser是一个简单,灵活的html解析器,允许您使用任何css选择器(如jQuery)选择标签。目标是协助开发需要快速,简单的方法来废弃html的工具,无论它是否有效!这个项目是由sunra / php-simple-html-dom-parser原创支持的,但支持似乎已经停止,所以这个项目是我对他以前工作的改编。
同样,我不推荐这个解析器。 CPU使用率很高,速度相当慢。还没有清除已创建DOM对象的内存的功能。这些问题尤其适用于嵌套循环。文档本身不准确且拼写错误,自4月14日以来没有对修复的响应。
- 通用标记器和HTML / XML / RSS DOM解析器
- 能够操纵元素及其属性
- 支持无效的HTML和UTF8
- 可以对元素执行类似CSS3的高级查询(比如jQuery - 支持的命名空间)
- HTML美化器(如HTML Tidy)
- 缩小CSS和Javascript
- 排序属性,更改字符大小写,更正缩进等。
- 扩展
- 使用基于当前字符/标记的回调解析文档
- 操作以较小的功能分隔,以便轻松覆盖
- 快速而简单
从未使用过它。不知道它是否有用。
您可以使用上面的解析HTML5,但是 可能有怪癖 由于HTML5允许的标记。因此,对于HTML5,您要考虑使用专用解析器,例如
基于WHATWG HTML5规范的HTML解析器的Python和PHP实现,可最大程度地兼容主要桌面Web浏览器。
HTML5最终确定后,我们可能会看到更多专用解析器。还有一个由W3标题为的博客文章 如何进行html 5解析 这值得一试。
如果您不想编写PHP,也可以使用Web服务。一般来说,我发现这些实用程序的效用很小,但这只是我和我的用例。
YQL Web服务使应用程序能够在Internet上查询,过滤和组合来自不同来源的数据。 YQL语句具有类似SQL的语法,对于具有数据库经验的任何开发人员来说都很熟悉。
ScraperWiki的外部界面允许您以您希望在Web或您自己的应用程序中使用的形式提取数据。您还可以提取有关任何刮刀状态的信息。
最后和 最不推荐的,您可以从HTML中提取数据 常用表达。通常,不鼓励在HTML上使用正则表达式。
您在网上找到的大多数与标记相匹配的片段都很脆弱。在大多数情况下,它们只适用于非常特殊的HTML。微小的标记更改,例如在某处添加空格,或添加或更改标记中的属性,可能会导致RegEx在未正确编写时失败。在HTML上使用RegEx之前,您应该知道自己在做什么。
HTML解析器已经知道HTML的语法规则。必须为您编写的每个新RegEx讲授正则表达式。 RegEx在某些情况下很好,但它实际上取决于您的用例。
您 可以编写更可靠的解析器但是写一个 完整可靠 具有正则表达式的自定义解析器在上述库已经存在并且在此方面做得更好时浪费时间。
另见 解析Html克苏鲁方式
如果你想花一些钱,看看吧
我不隶属于PHP Architect或作者。
// 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>';
// 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;
// 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);
只是用 上一层> loadHTML() 并完成它。 libxml的HTML解析算法非常好而且速度快,而且与普遍看法相反,它不会阻碍格式错误的HTML。
为什么你不应该和 什么时候应该 使用正则表达式?
首先,一个常见的误称:Regexps不适合 “解析“ HTML。但是,正则表达式可以 “提取“ 数据。提取是他们的目标。正则表达式HTML提取优于正确的SGML工具包或基线XML解析器的主要缺点是它们的语法功能和不同的可靠性。
考虑制作一个有点可靠的HTML提取正则表达式:
<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");
但是有一些具体的用例,他们可以提供帮助。
<!--
然而,它有时是更有用的提取锚。特别是伪HTML变体 <$var>
或者SGML残留物很容易用正则表达式来驯服。有时甚至建议使用正则表达式预提取HTML片段 /<!--CONTENT-->(.+?)<!--END-->/
并使用更简单的HTML解析器前端处理剩余部分。
注意: 我实际上有这个 应用,我在那里使用XML解析和正则表达式。就在上周,PyQuery解析破了,正则表达式仍然有效。是的很奇怪,我自己无法解释。但事情发生了。
因此,请不要将现实世界的考虑因素投反对票,因为它与正则表达式=邪恶的模因不符。 但是,我们也不要过多地投票。这只是本主题的旁注。
phpQuery 和 的QueryPath 在复制流畅的jQuery API方面非常相似。这也是为什么他们是最简单的两种方法 正确 用PHP解析HTML。
QueryPath的示例
基本上,您首先从HTML字符串创建可查询的DOM树:
$qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL
生成的对象包含HTML文档的完整树表示。它可以使用DOM方法遍历。但常见的方法是使用jQuery中的CSS选择器:
$qp->find("div.classname")->children()->...;
foreach ($qp->find("p img") as $img) {
print qp($img)->attr("src");
}
大多数情况下你想使用简单 #id
和 .class
要么 DIV
标签选择器 ->find()
。但你也可以使用 XPath的 陈述,有时更快。也是典型的jQuery方法 ->children()
和 ->text()
特别是 ->attr()
简化提取正确的HTML代码段。 (已经解码了他们的SGML实体。)
$qp->xpath("//div/p[1]"); // get first paragraph in a div
QueryPath还允许将新标记注入流中(->append
),然后输出并美化更新的文件(->writeHTML
)。它不仅可以解析格式错误的HTML,还可以解析各种XML方言(带名称空间),甚至可以从HTML微格式(XFN,vCard)中提取数据。
$qp->find("a[target=_blank]")->toggleClass("usability-blunder");
。
phpQuery还是QueryPath?
通常,QueryPath更适合处理文档。虽然phpQuery也实现了一些伪AJAX方法(只是HTTP请求),更接近jQuery。据说phpQuery通常比QueryPath更快(因为整体功能较少)。
有关差异的更多信息,请参阅 这是来自tagbyte.org的回程机器的比较。 (原始来源丢失了,所以这里是一个互联网档案链接。是的,你仍然可以找到丢失的页面,人。)
而且这里 一个全面的QueryPath介绍。
优点
->find("a img, a object, div a")
简单的HTML DOM是一个很好的开源解析器:
它以面向对象的方式处理DOM元素,并且新的迭代对非兼容代码有很多覆盖。还有一些很棒的函数,比如你在JavaScript中看到的,比如“find”函数,它将返回该标记名称的所有元素实例。
我已经在许多工具中使用它,在许多不同类型的网页上测试它,我认为它很有用。
我在这里没有提到的一个通用方法是运行HTML 整洁,可以设置为吐出保证有效的XHTML。然后您可以在其上使用任何旧的XML库。
但是对于您的具体问题,您应该看看这个项目: http://fivefilters.org/content-only/ - 它是改进版的 可读性 算法,旨在从页面中仅提取文本内容(不是页眉和页脚)。
对于1a和2:我会投票支持新的Symfony Componet类DOMCrawler( DomCrawler )。 此类允许类似于CSS选择器的查询。看一下这个演示文稿,了解真实世界的例子: 新闻的最Symfony2的世界。
该组件设计为独立工作,无需Symfony即可使用。
唯一的缺点是它只适用于PHP 5.3或更高版本。
这通常被称为 屏幕抓取, 顺便一提。我用过的库是 简单的HTML Dom Parser。
我们之前已经为我们的需求创建了很多爬虫。在一天结束时,通常是简单的正则表达式来做最好的事情。虽然上面列出的库很好,因为它们是创建的,如果你知道你在寻找什么,正则表达式是一种更安全的方式,因为你也可以处理无效的 HTML/XHTML 结构,如果通过大多数解析器加载,将失败。