php - PHP里你是怎么分析和处理html / XML?

  显示原文与译文双语对照的内容

如何解析 html/xml并从中提取信息?

于该 相关标签, 这是一个一般参考问题

时间:

原生XML扩展

我宁愿使用的native-xml扩展之一,因为它们会捆绑 PHP,通常速度比所有的3研究和开发方的标记上libs然后给我所有我需要的控件。

DOM扩展允许你通过带有 PHP 5的DOM API在XML文档上操作。 它是w3c对象模型核心 3的文档的实现,它是一个platform-和language-neutral界面,允许程序和脚本动态访问和更新文档的内容,结构和样式。

DOM能够解析和修改真实世界的( 断开) HTML,它可以执行 XPath查询。 它基于 libxml

用DOM来提高生产力需要一些时间,但这是值得的。 因为DOM是一个language-agnostic接口,你会发现很多语言的实现,所以如果你需要更改编程语言,那么你就已经知道如何使用该语言API了。

DOMDocument将关于内存href属性中可以找到在php的,基本用法示例中可以找到一个元素和一个一般人的概念概述

如何使用DOM扩展在 StackOverflow 中得到了广泛的讨论,因此,如果你选择使用它,你可以通过搜索/浏览堆栈溢出来解决大多数问题。

XMLReader

XMLReader扩展是一个 XML pull解析器。 读取器充当一个光标,在文档流前进并在每个节点上停止。

XMLReader和DOM一样,基于 libxml 。 我不知道如何触发HTML解析器模块,所以有机会使用XMLReader解析坏掉的HTML可能是 LESS 健壮的,你可以明确地告诉它使用libxml解析器模块的HTML 。

处可以找到基本用法示例,使用 php 从h1标签获取所有值

XML解析器

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

XML解析器库也基于 libxml,并实现了一个 SAX 样式XML推送解析器。 对于内存管理来说,它可能比DOM或者SimpleXML更好的内存管理,但比由XMLReader实现的pull解析器更难。

SimpleXml

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

当你知道HTML是有效的XHTML时,SimpleXML是一个选项。 如果你需要解析坏掉的HTML,不要考虑 SimpleXml,因为它会阻塞。

PHP手册,一个基本的使用说明中的示例可以在找到一个示例程序,CRUD节点和节点值的xml文件和有大量的额外 examples.


第三方库( 基于 libxml )

如果你喜欢使用 3 rd-party库,我建议使用一个实际使用 DOM/libxml的lib,而不是字符串解析。

phpQuery

phpQuery是一个 server-side,可以链接的,CSS3选择器驱动的文档对象模型( DOM ) API,基于用PHP5编写的jQuery JavaScript库,提供额外的命令行 接口( CLI ) 。

Zend_Dom

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

QueryPath

QueryPath是一个用于操作XML和HTML的PHP库。 它不仅可以用于本地文件,还可以用于 Web服务 和数据库资源。 它实现了许多jQuery接口( 包括CSS-style选择器),但是它对server-side使用进行了大量的调优。 可以通过编辑器安装。

FluentDom

FluentDOM为在PHP中的DOMDocument提供一个jQuery-like流畅的XML接口。 选择器是用XPath或者 CSS ( 使用CSS转换为XPath转换器) 编写的。 当前版本扩展了实现标准接口的DOM,并从DOM生活标准添加特性。 FluentDOM可以加载 JSON,CSV,JsonML,RabbitFish等格式。 可以通过编辑器安装。

fDOMDocument

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


3rd-Party ( 不是 libxml-based )

构建在 dom/libxml之上的好处是,你可以从该框获得良好的性能,因为你基于本机扩展。 然而,并非所有 3 rd-party库都沿着这个路由。 下面列出了其中的一些

SimpleHtmlDom

  • 用PHP5+编写的一个 HTML DOM解析器允许你以非常简单的方式操作 HTML !
  • 需要 PHP 5 + 。
  • 支持无效的HTML 。
  • 在带有选择器的HTML页面上查找标记,就像 jQuery 。
  • 在单行中从HTML中提取内容。

我一般不推荐这个解析器。 代码库很可怕,解析器本身相当慢,内存也在消耗。 任何基于libxml的库都应该比这个简单。

Ganon

  • 一个通用记号赋予器和 HTML/XML/RSS DOM解析器
    • 操纵元素及其属性的能力
    • 支持无效的HTML和 UTF8
  • 可以对元素执行高级CSS3-like查询( 比如支持的jQuery --命名空间)
  • 一个HTML美化器( 比如 HTML Tidy )
    • 缩小CSS和 Javascript
    • 排序属性,更改字符大小写,更正缩进等。
  • 可以扩展
    • 使用基于当前字符/标记的回调分析文档
    • 以较小的函数分隔的操作,以方便覆盖
  • 快速轻松

没用的,我不知道它是不是好的。


HTML 5

你可以使用上面的方法解析 HTML5,但是可能会因为标记HTML5而有问题。 因此,对于 HTML5,你需要考虑使用一个专用解析器,比如

html5lib

基于 WHATWG HTML5规范的HTML和PHP实现,以最大限度地兼容主流的桌面浏览器。

一旦HTML5完成,我们可能会看到更多专用解析器。 还有一个标题为 w3 How-To的blogpost,用于 html 5解析,它值得检查。


web元

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

YQL

YQL网络服务使应用程序能够查询,筛选和合并来自互联网不同来源的数据。 YQL语句有一个SQL-like语法,对于任何有数据库经验的开发者都很熟悉。

ScraperWiki

scraperwiki接口外部允许你在站点或者你自己的应用程序中使用你想要的表单提取数据。 你还可以提取有关任何刮板状态的信息。


yf_terminology_Regular Expressions@#@#@#正规表达式_yf_terminology

正规表达式, 最后和最小推荐,你可以从HTML中提取数据 通常不鼓励在HTML上使用 正规表达式 。

你在站点上找到的与标记匹配的大部分Fragment都是脆弱的。 大多数情况下,它们只适用于一个非常特殊的HTML 。 微小标记更改,比如在某处添加空白或者添加或者更改标记中的属性,可以使 正规表达式 在没有正确写入时失败。 在使用 正规表达式 之前,你应该知道你正在做什么。

HTML解析器已经知道HTML的语法规则。 正规表达式 必须为你编写的每个新 正规表达式 进行教学。 正规表达式 在某些情况下很好,但它真的取决于你的use-case 。

在你 this, 可以编写多个解析器可靠,但编写一个自定义的剖析器,而完整和可靠 正规表达式 是一种浪费时间当前面提到的库已经存在并且做了更好的工作,但

也见解析 Html Cthulhu方式


书籍

如果你想花一些钱,看看

我与PHP架构师或者作者不相关。

试用 简单的HTML Dom解析器

  • 用PHP5+编写的一个 HTML DOM解析器允许你以非常简单的方式操作 HTML !
  • 需要 PHP 5 + 。
  • 支持无效的HTML 。
  • 在带有选择器的HTML页面上查找标记,就像 jQuery 。
  • 在单行中从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;


对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);

只需使用 DOMDocument-> loadHTML() web service并完成它。 libxml解析算法的HTML非常好和快,与流行的信念相反,它不会阻塞格式不正确的HTML 。

phpQueryQueryPath在复制流畅的jQuery API中非常相似。 php,中这也是为什么它们是最简单的有两种方法来正确 解析 HTML

于QueryPath相关, 示例

基本上你首先从一个HTML字符串创建一个可以查询的DOM树:


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

结果对象包含一个完整的HTML文档树表示。 可以使用DOM方法进行遍历。 但是常用的方法是使用CSS选择器,比如 jQuery:


 $qp->find("div.classname")->children()->...;

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

大多数情况下,你需要使用简单的#id.class 或者 DIV 标记选择器。 但你也可以使用 XPath 语句,这些语句有时更快。 ->children()->text() 等典型的jQuery方法,特别是 ->attr(),简化了对正确的HTML Fragment的提取。 ( 并且已经解码了它们的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")
  • 正确的数据重建( 与正则表达式grepping相比)

为什么你不应该和当你应该使用 正规表达式

合理地利用什么先HTML无法解析. regex可以但是 数据提取。 提取是它们所做的。 在正确的SGML工具包或者基本的XML解析器上提取 正规表达式的主要缺点是它们的语法cumbersomeness和贫乏的可靠性。

假设制作一个可靠的HTML提取 正规表达式:


<as+class="?playbuttond?[^>]+id="(d+)".+? <as+class="[ws]*title
[ws]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?

比简单的phpQuery或者QueryPath的可读性要低:


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

但有特定的用例可以帮助他们。 大多数XML解析器都无法看到HTML文档注释 <--,但它们有时是用于提取目的的更有用的标记。! 偶尔 正规表达式 可以保存 post-processing 。 最后,对于非常简单的任务,比如提取 <src= url,它们实际上是一个可能的工具。 在 sgml/xml解析器上的速度优势主要是用来处理这些非常基本的提取过程。

甚至使用它有时被明智pre-extract一个Fragment超文本标记语言 /<!--CONTENT-->(.+?)<!--END-->/ 使用简单的HTML解析器方法处理余数。

注意: 其实我有这个 应用程序 我使用了XML解析和 正规表达式 。 就在上周PyQuery解析失败,正规表达式 仍然工作。 是的,奇怪,我不能自己解释。 但它发生了。
所以,请不要在现实世界中投票,因为它与 regex=evil meme不匹配。 了,但我们也不把它 vote 。 这只是本主题的一部分。

我建议使用 phpQuery

简单的HTML Dom是一个很棒的open-source解析器:

simplehtmldom.sourceforge

它以object-oriented方式处理dom元素,新的迭代对non-compliant代码有很多覆盖。 还有一些很棒的函数,如你在JavaScript中看到的,比如"查找"函数,它将返回该标记名称的所有元素的所有实例。

我在许多不同的网页上使用过这个工具,测试它,我认为它很有用。

这里提到一个通用的方法我还没有看到是运行HTML通过整齐,可以设置该属性以吐出 guaranteed-valid XHTML中。 然后你可以使用任何旧的XML库。

但是对于你的具体问题,你应该看看这个项目: http://fivefilters.org/content-only/ --是可读性算法的修改版本,它旨在从一个页面中提取文本内容( 不是页眉和页脚) 。

对于 1和 2: 我将为新的Symfony组件类 DomCrawler ( DomCrawler ) 投票。 此类允许类似于CSS选择器的查询。 查看这里演示文稿以了解真实示例: news-of-the-symfony2-world

组件设计为独立工作,并且无需Symfony即可使用。

唯一的缺点是它只适用于 PHP 5.3或者更高版本。

这通常被称为收费 screen,顺便说一下。 我使用的库是简单的HTML Dom解析器

...