如何在PHP中解析和处理HTML/XML?
如何解析HTML/XML并从中提取信息?是相当稳定的,即使不再维护它。另一种选择是通过管道传递HTML,然后使用标准XML工具对其进行解析。简单HTML DOM是一种很棒的开源解析器: 它以面向对象的方式处理DOM元素,新的迭代覆盖了大量不兼容的代码。还有一些很棒的函数,如JavaScript中的find函数,它将返回该标记名元素的所有实例如何在PHP中解析和处理HTML/XML?,php,xml,parsing,xml-parsing,html-parsing,Php,Xml,Parsing,Xml Parsing,Html Parsing,如何解析HTML/XML并从中提取信息?是相当稳定的,即使不再维护它。另一种选择是通过管道传递HTML,然后使用标准XML工具对其进行解析。简单HTML DOM是一种很棒的开源解析器: 它以面向对象的方式处理DOM元素,新的迭代覆盖了大量不兼容的代码。还有一些很棒的函数,如JavaScript中的find函数,它将返回该标记名元素的所有实例 我已经在很多工具中使用了它,在许多不同类型的网页上测试了它,我认为它工作得很好。您可以尝试使用类似于清理任何损坏的HTML并将HTML转换为XHTML的东西
我已经在很多工具中使用了它,在许多不同类型的网页上测试了它,我认为它工作得很好。您可以尝试使用类似于清理任何损坏的HTML并将HTML转换为XHTML的东西,然后您可以使用XML解析器进行解析。只要使用它就可以了。libxml的HTML解析算法非常好且快速,而且与流行的观点相反,它不会被格式错误的HTML阻塞。试试看 一个用PHP5+编写的HTMLDOM解析器,可以让您以非常简单的方式操作HTML! 需要PHP5+。 支持无效的HTML。 使用选择器在HTML页面上查找标记,就像jQuery一样。 在一行中从HTML中提取内容。 如何获取HTML元素: 刮削斜杠: 本机XML扩展 我更喜欢使用其中的一个,因为它们与PHP捆绑在一起,通常比所有第三方lib都快,并提供了我需要的对标记的所有控制 DOM扩展允许您使用PHP5通过DOM API对XML文档进行操作。它是W3C文档对象模型核心级别3的实现,是一个平台和语言中立的界面,允许程序和脚本动态访问和更新文档的内容、结构和样式 DOM能够解析和修改现实世界中被破坏的HTML,它可以做到这一点。它是基于 使用DOM需要一些时间才能提高效率,但在我看来,这是非常值得的。因为DOM是一个与语言无关的接口,您可以在许多语言中找到实现,因此如果您需要更改编程语言,那么您可能已经知道如何使用该语言的DOM API 在中可以找到基本用法示例,在中可以找到一般概念概述 ,因此,如果您选择使用它,您可以确保您遇到的大多数问题都可以通过搜索/浏览堆栈溢出来解决 XMLReader扩展是一个XML拉式解析器。读卡器充当文档流上前进的光标,并在途中的每个节点处停止 与DOM一样,XMLReader也是基于libxml的。我不知道如何触发HTML解析器模块,因此使用XMLReader解析损坏的HTML可能不如使用DOM(在DOM中可以显式告诉它使用libxml的HTML解析器模块)健壮 有关基本用法示例,请访问 此扩展允许您创建XML解析器,然后为不同的XML事件定义处理程序。每个XML解析器也有一些可以调整的参数 XML解析器库也基于libxml,并实现了一个样式XML推式解析器。对于内存管理来说,它可能比DOM或SimpleXML更好,但与XMLReader实现的pull解析器相比,它更难使用 SimpleXML扩展提供了一个非常简单且易于使用的工具集,用于将XML转换为可以使用普通属性选择器和数组迭代器处理的对象 当您知道HTML是有效的XHTML时,SimpleXML是一个选项。如果需要解析损坏的HTML,不要考虑SimeXML,因为它会哽住。< /P> 基本用法示例可在中找到,并且有 基于libxml的第三方库 如果您更喜欢使用第三方库,我建议使用实际使用/under的库,而不是字符串解析 - FluentDOM为PHP中的DOMDocument提供了类似于jQuery的FluentXML接口。选择器是使用CSS到XPath转换器以XPath或CSS编写的。当前版本扩展了DOM实现的标准接口,并添加了来自DOM生活标准的特性。FluentDOM可以加载JSON、CSV、JsonML、RabbitFish等格式。可以通过Composer安装 Wa72\HtmlPageDom`是一个易于操作HTML的PHP库 使用它的文档需要遍历 DOM树,并通过添加操作DOM的方法对其进行扩展 HTML文档树 多年未更新 phpQuery是一个服务器端、可链接、CSS3选择器驱动的文档对象模型domapi,基于PHP5编写的jqueryjavascript库,并提供额外的命令行界面CLI 另见: Zend_Dom提供了用于处理Dom文档和结构的工具。目前,我们提供了Zend_Dom_查询,它为使用XPath和CSS选择器查询Dom文档提供了统一的接口 QueryPath是一个PHP库 很少使用XML和HTML。它不仅设计用于本地文件,还设计用于web服务和数据库资源。它实现了jQuery界面的大部分功能,包括CSS样式选择器,但是它为服务器端使用进行了大量的调优。可以通过Composer安装 fDOMDocument扩展了标准DOM,使其在所有错误情况下都使用异常,而不是PHP警告或通知。为了方便和简化DOM的使用,它们还添加了各种自定义方法和快捷方式 sabre/xml是一个库,它包装和扩展XMLReader和XMLWriter类,以创建简单的xml到对象/数组映射系统和设计模式。编写和读取XML只需一次,因此速度很快,并且在大型XML文件上需要较低的内存 FluidXML是一个PHP库,用于使用简洁流畅的API处理XML。 它利用XPath和fluent编程模式使其变得有趣和有效 第三方不基于libxml 基于DOM/libxml构建的好处是,由于您基于本机扩展,因此可以立即获得良好的性能。然而,并不是所有的第三方LIB都走这条路。下面列出了其中一些 用PHP5+编写的HTMLDOM解析器可以让您以非常简单的方式操作HTML! 需要PHP5+。 支持无效的HTML。 使用选择器在HTML页面上查找标记,就像jQuery一样。 在一行中从HTML中提取内容。 我通常不推荐使用这种解析器。代码库很糟糕,解析器本身速度很慢,内存不足。并非所有jQuery选择器都可以使用,例如。任何基于libxml的库都应该能够轻松地超越这一点 phtmlparser是一个简单、灵活的html解析器,它允许您使用任何css选择器(如jQuery)选择标记。我们的目标是帮助开发需要快速、简单的方法来获取html的工具,不管它是否有效!这个项目最初由sunra/php simple HTMLDOM解析器支持,但支持似乎已经停止,所以这个项目是我对他以前工作的改编 同样,我不推荐使用这种解析器。它相当慢,CPU使用率很高。也没有清除已创建DOM对象内存的功能。这些问题尤其适用于嵌套循环。文档本身不准确,拼写错误,自2016年4月14日以来没有对修复的响应 通用标记器和HTML/XML/rssdom解析器 像HTML一样的HTML美化器 可扩展 快捷 从来没用过。看不出有什么好处 HTML 5 您可以使用上述方法解析HTML5,但由于HTML5允许的标记。所以对于HTML5,你要考虑使用一个专用的解析器,比如 基于WHATWG HTML5规范的HTML解析器的Python和PHP实现,最大限度地与主要桌面web浏览器兼容 一旦HTML5最终确定,我们可能会看到更多的专用解析器。W3还有一篇题为“值得一看”的博客文章 的集成 如果您不想编写PHP,也可以使用Web服务。一般来说,我发现这些工具的实用性很小,但这只是我和我的用例 . ScraperWiki的外部接口允许您以希望在web或您自己的应用程序中使用的形式提取数据。您还可以提取有关任何刮板状态的信息 正则表达式 最后也是最不推荐的,您可以使用从HTML提取数据。通常不鼓励在HTML上使用正则表达式 在web上找到的大多数与标记匹配的代码片段都是脆弱的。在大多数情况下,它们只适用于非常特殊的HTML片段。微小的标记更改,如在某个地方添加空白,或在标记中添加或更改属性,可能会使正则表达式在未正确编写时失败。在HTML上使用正则表达式之前,您应该知道自己在做什么 HTML解析器已经知道HTML的语法规则。必须为您编写的每个新正则表达式教授正则表达式。在某些情况下,正则表达式是很好的,但它实际上取决于您的用例 但是,当前面提到的库已经存在并且在这方面做得更好时,用正则表达式编写一个完整可靠的自定义解析器是浪费时间的 也看到 书 如果你想花点钱,看看
我与PHP架构师或其作者无关。顺便说一句,这通常被称为屏幕抓取。我用于此的库是。用于1a和2:我将投票支持新的Symfony Componet类DOMCrawler。 此类允许类似于CSS选择器的查询。请看本演示文稿,了解真实世界的示例: 该组件设计为独立工作,可以在没有Symfony的情况下使用 唯一的缺点是,它只适用于PHP5.3或更高版本。为什么不应该以及何时应该使用正则表达式 首先,一个常见的误称 r:regexp不用于解析HTML。不过,正则表达式可以提取数据。这就是它们的用途。相对于合适的SGML工具包或基线XML解析器,regex HTML提取的主要缺点是它们的语法工作和不同的可靠性 考虑一下,制作一个稍微可靠的HTML提取正则表达式:
<a\s+class="?playbutton\d?[^>]+id="(\d+)".+? <a\s+class="[\w\s]*title
[\w\s]*"[^>]+href="(http://[^">]+)"[^>]*>([^<>]+)</a>.+?
然而,有一些特定的用例可以提供帮助
许多DOM遍历前端不显示HTML注释,但它们有时是用于提取的更有用的锚。特别是伪HTML变体或SGML残基很容易用regexp驯服。
通常,正则表达式可以节省后期处理。然而,HTML实体通常需要手动看护。
最后,对于非常简单的任务,如提取
有时甚至建议使用正则表达式/+?/预提取HTML片段,并使用更简单的HTML解析器前端处理剩余部分
注意:实际上我有这个,在这里我交替使用XML解析和正则表达式。就在上周,PyQuery解析中断,正则表达式仍然有效。是的,很奇怪,我自己也解释不了。但事情就这样发生了。
所以请不要因为现实世界中的考虑因素与regex=evil模因不匹配就否决它。但我们也不要对此投太多的票。这只是本主题的旁注。使用DOM而不是字符串解析的SimpleHtmlDom的第三方替代品:,和。在复制fluent jQuery API方面非常相似。这也是为什么它们是在PHP中正确解析HTML的两种最简单的方法 查询路径示例 基本上,首先从HTML字符串创建一个可查询的DOM树:
$qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL
大多数情况下,您希望为->查找使用简单的id和.class或DIV标记选择器。但您也可以使用语句,有时会更快。另外,典型的jQuery方法,如->children和->text,尤其是->attr,可以简化提取正确的HTML片段的过程。并且已经解码了他们的SGML实体
$qp->xpath("//div/p[1]"); // get first paragraph in a div
QueryPath还允许将新标记注入流->追加,然后输出并美化更新的文档->writeHTML。它不仅可以解析格式错误的HTML,还可以解析带有名称空间的各种XML方言,甚至可以从HTML微格式XFN、vCard中提取数据
$qp->find("a[target=_blank]")->toggleClass("usability-blunder");
phpQuery还是QueryPath
通常,QueryPath更适合于文档的操作。虽然phpQuery还实现了一些伪AJAX方法,但只是HTTP请求更像jQuery。据说phpQuery通常比QueryPath更快,因为它的总体特性更少
有关差异的更多信息,请参阅。原始资料不见了,这里有一个互联网档案链接。是的,你仍然可以找到丢失的页面,人们
这是我的
优势
简单可靠
简单易用的备选方案->finda img,对象,分区a
与正则表达式grepping相比,正确的数据消除
这听起来像是对W3C技术的一个很好的任务描述。很容易表达查询,如返回嵌套在元素中的img标记中的所有href属性。我不是PHP爱好者,我无法告诉您XPath的可用形式。如果可以调用外部程序来处理HTML文件,则应该能够使用命令行版本的XPath。
有关快速介绍,请参见。我在这里没有提到的一种通用方法是运行HTML,可以设置为吐出保证有效的XHTML。然后您可以在它上面使用任何旧的XML库
但是对于您的具体问题,您应该看看这个项目:-它是算法的一个修改版本,旨在从页面中提取文本内容,而不是页眉和页脚 您可以尝试的另一个选项是。它的灵感来源于jQuery,但在服务器上使用PHP并在中使用。我们以前为我们的需要创建了很多爬虫程序。最后,通常是简单的正则表达式做得最好。虽然上面列出的库之所以创建是因为它们很好,但如果您知道您在寻找什么,正则表达式是一种更安全的方法,因为您还可以处理无效的/结构,如果通过大多数解析器加载,则会失败。该框架具有可以解析HTML的捆绑包,您可以使用CSS样式来选择,而不是使用。是的,您可以使用simple\u html\u dom。然而,我在simple_html_dom上做了很多工作,特别是在web抓取方面,我发现它太脆弱了。它做的基本工作,但我不会推荐它无论如何 我从未使用过curl,但我学到的是,curl可以更有效地完成这项工作,而且更可靠 请查看此链接:QueryPath很好,但要注意跟踪状态,因为如果您没有意识到它的含义,这可能意味着您要浪费大量调试时间来找出发生了什么 以及为什么代码不起作用 这意味着对结果集的每次调用都会修改对象中的结果集,它不像jquery中的每个链接都是一个新的集合那样是可链接的,您有一个集合,它是查询的结果,每个函数调用都会修改这个集合 为了获得类似jquery的行为,您需要在执行类似筛选/修改的操作之前进行分支,这意味着它将更紧密地反映jquery中发生的事情
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$results现在包含输入[name='forename']的结果集,而不是原始的查询div p。这让我大吃一惊,我发现QueryPath跟踪过滤器并查找所有修改结果并将其存储在对象中的内容。你需要这样做
$forename = $results->branch()->find("input[name='forname']")
这样$results就不会被修改,您可以一次又一次地重复使用结果集,也许有更多知识的人可以稍微澄清一下,但从我的发现来看,基本上是这样的。我推荐
它确实有很好的功能,比如:
foreach($html->find('img') as $element)
echo $element->src . '<br>';
我已经编写了一个通用XML解析器,可以轻松地处理GB文件。它基于XMLReader,非常易于使用:
$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
echo $tag->field1;
echo $tag->field2->subfield1;
}
这是github的报告:因为,html5库已经被废弃多年了。我能找到的唯一一个有最新更新和维护记录的HTML5库是一周多前刚刚发布到beta 1.0版的。JSON和array from XML分为三行:
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
塔达 不使用正则表达式解析HTML有几个原因。但是,如果您可以完全控制将生成什么HTML,那么您可以使用简单的正则表达式 上面是一个通过正则表达式解析HTML的函数。请注意,此函数非常敏感,要求HTML遵守某些规则,但它在许多情况下工作得非常好。如果您想要一个简单的解析器,但不想安装库,请尝试一下:
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/")));
有许多方法可以处理HTML/XMLDOM,其中大多数已经提到。因此,我本人不会尝试列出这些 我只想补充一点,我个人更喜欢使用DOM扩展,为什么: iit充分利用了底层C代码的性能优势 它是OO PHP,允许我对它进行子类化 这是相当低的水平,允许我使用它作为一个非臃肿的基础更先进的行为。 它提供对DOM的每个部分的访问,不像SimpleXml,它忽略了一些鲜为人知的XML特性 它有一个用于DOM爬网的语法,与本机Javascript中使用的语法类似。 虽然我错过了为DOMDocument使用CSS选择器的功能,但有一种非常简单方便的方法可以添加此功能:对DOMDocument进行子类化,并向子类添加类似于querySelectorAll和querySelector的JS方法 为了解析选择器,我建议使用。这个组件只是将CSS选择器转换为XPath选择器,然后可以将其输入到DOMXpath中以检索相应的节点列表
您可以使用这个仍然非常低级别的子类作为更高级别类的基础,旨在解析特定类型的XML或添加更多类似jQuery的行为。 下面的代码是我的代码,使用了我描述的技术
对于HTML解析: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的创建者Fabien Povertier关于他为Symfony创建CssSelector组件的决定以及如何使用它的内容。是一个简单的HTML替换,提供了相同的界面,但它基于DOM,这意味着不会出现任何相关的内存问题
它还具有完整的CSS支持,包括扩展。我创建了一个名为的库,它允许您像使用jQuery一样抓取HTML5和XML文档
在引擎盖下,它用于将CSS选择器转换为选择器。它总是使用相同的DomDocument,即使在将一个对象传递给另一个对象时也是如此,以确保良好的性能
示例用法:
支持的方法:
[x] 一,
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x] 二,
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
[x]
更名为“选择”,原因显而易见
重命名为“void”,因为“empty”在PHP中是保留字
注:
该库还包括它自己的用于PSR-0兼容库的零配置自动加载器。所包含的示例应该是开箱即用的,不需要任何额外的配置。或者,您可以将它与composer一起使用。使用它,您可以使用XPath和CSS选择器查询和迭代XML
我创建了一个名为HTML5DOMDocument的库,可以在 它还支持查询选择器,我认为这对您的情况非常有帮助。下面是一些示例代码:
$dom = new IvoPetkov\HTML5DOMDocument();
$dom->loadHTML('<!DOCTYPE html><html><body><h1>Hello</h1><div class="content">This is some text</div></body></html>');
echo $dom->querySelector('h1')->innerHTML;
如果您熟悉jQuery选择器,您可以使用 此库处理脱机html通常不到1秒。 它还接受无效的HTML或缺少的引号
关于标记属性。解析xml的最佳方法:
符合事实的它与PHP内置的XPath和XSLTProcessor类一起工作,这两个类对于提取内容非常有用。对于真正损坏的HTML,您可以在将其交给DOM之前通过htmltidy运行它。每当我需要从HTML中提取数据时,我总是使用DOM,或者至少是simplexml。加载格式不正确的HTML的另一件事是,调用libxml\u use\u internal\u errorstrue以防止停止解析的警告可能是明智的。我使用DOMDocument解析了大约1000个使用不同字符集编码的不同语言的HTML源,没有任何问题。您可能会遇到编码问题,但这些问题并非无法解决。您需要知道3件事:1 loadHTML使用meta标记的字符集来确定编码2如果html内容不包含此信息,则可能导致错误的编码检测3错误的UTF-8字符可能会使解析器出错。在这种情况下,结合使用mb_detect_编码和Simplepie RSS解析器的编码/转换/剥离坏的UTF-8字符代码来解决问题。DOM实际上支持XPath,请看一看。严格来说,这不是真的。线索在屏幕上;在所描述的案例中,没有涉及屏幕。虽然,不可否认,这个术语最近遭到了大量的误用。我不是屏幕抓取,将被解析的内容将由内容供应商根据我的协议授权。首先,我需要准备一些东西,比如坏DOM,Invlid代码,还有js对DNSBL引擎的分析,这还将用于查找恶意网站/内容,同时,由于我已经围绕一个框架构建了我的网站,因此它需要干净、可读、结构良好。SimpleDim很好,但是代码稍微有些复杂messy@Robert你可能还想检查一下与安全相关的东西,他有一个正确的观点:simpleHTMLDOM很难扩展,除非你使用decorator模式,我觉得这很难扩展。我发现自己对底层类本身进行更改时会不寒而栗。我所做的是在发送给SimpleDOM之前通过tidy运行html。我目前正在使用它,将其作为一个项目的一部分来运行,以处理几百个URL。它变得非常缓慢,并且经常超时。这是一个很棒的初学者脚本,直观地说学习起来很简单,但对于更高级的项目来说太基础了。@Naveed,这取决于您的需要。我不需要CSS选择器查询,这就是为什么我只使用DOM和XPath。phpQuery的目标是成为jQuery端口。Zend_Dom是轻量级的。你真的必须检查一下,看看你最喜欢哪一个。@Ms2ger大部分,但不是全部。正如上面已经指出的,您可以使用基于libxml的解析器,但在某些特殊情况下,这些解析器会阻塞。如果您需要最大的兼容性,最好使用专用的解析器。我更愿意保持这种区别。你不使用PHP简单HTML DOM解析器的观点似乎没有意义。截至2012年3月29日,DOM不支持html5,XMLReader不支持HTML,最后一次提交PHP的html5lib是在2009年9月。用什么来解析HTML5、HTML4和XHTML?@Nasha我故意将臭名昭著的Zalgo rant从上面的列表中排除,因为它本身并没有太大帮助,而且自它被编写以来就导致了相当多的货物崇拜。无论正则表达式作为一种解决方案有多么合适,人们都会被这个链接打倒。要获得更平衡的意见,请查看我包含的链接,并浏览can read comments上的注释,因此没有理由为此使用正则表达式。SGML工具包或XML解析器都不适合解析真实世界的HTML。为此,只有一个专用的HTML解析器才合适。@Alohci使用和模块,在加载HTML时将使用和模块,因此它可以非常多地加载真实世界中的已读损坏的HTML。好吧,请对您的真实世界观点发表评论。当然,在解析HTML时,正则表达式有一些有用的情况。使用GOTO也有一些有用的情况。对于可变变量也有一些有用的情况。因此,没有一个特定的实现是使用它的最终代码腐烂。但这是一个非常强烈的警告信号。而一般的开发人员不太可能有足够的细微差别来区分两者之间的区别。所以一般来说,正则表达式GOTO和变量都是邪恶的。有非邪恶的用途,但这些是例外和罕见的。。。IMHO@mario:事实上,HTML可以使用正则表达式“正确”解析,尽管通常需要几个正则表达式才能完成一项公平的工作。在一般情况下,这只是皇家的痛苦。在具有定义良好的输入的特定情况下,它几乎是微不足道的。人们应该在这些情况下使用正则表达式。一般情况下,您确实需要大的、陈旧的、笨重的解析器,尽管对于普通用户来说,这条线在哪里并不总是清晰的。无论哪种代码更简单、更容易,都会赢。如果你已经复制了我的评论,至少要正确链接它们;那应该是:建议三
d方的替代方法实际上是使用,而不是字符串解析:,和。好的答案是一个很好的来源。curl可以获取该文件,但不能为您解析HTML。这是最难的部分。类似jquery的css查询说得很好,因为w3c文档中缺少了一些东西,但在jquery中作为额外功能出现。看起来是适合这项工作的工具,但在Worpress的PHP5.6.23中没有为我加载。关于如何正确包含它的任何其他说明?。包括:defineBASE_PATH,dirnameFILE;定义库路径,基本路径。目录“”分隔符lib/供应商';需要库路径。目录“”分隔符php';装入器::initarrayLIBRARY\u路径,用户路径;在functions.phpI中,我们已经从高级HTMLDOM中获得了很好的结果,我认为它应该在公认答案的列表中。但是,对于任何依赖它的人来说,需要知道的一件重要事情是,这个项目的目标是成为一个基于DOM的插件,以替代PHP的简单html DOM库。。。如果使用file/str\u get\u html,则无需更改任何内容。您可能需要对代码进行更改以适应某些不兼容性。在项目的github问题中,我注意到了四个已知的问题。
$div->find(".stationcool a")->attr("title");
$qp = qp("<html><body><h1>title</h1>..."); // or give filename or URL
$qp->find("div.classname")->children()->...;
foreach ($qp->find("p img") as $img) {
print qp($img)->attr("src");
}
$qp->xpath("//div/p[1]"); // get first paragraph in a div
$qp->find("a[target=_blank]")->toggleClass("usability-blunder");
$results = qp("div p");
$forename = $results->find("input[name='forename']");
$forename = $results->branch()->find("input[name='forname']")
foreach($html->find('img') as $element)
echo $element->src . '<br>';
$source = new XmlExtractor("path/to/tag", "/path/to/file.xml");
foreach ($source as $tag) {
echo $tag->field1;
echo $tag->field2->subfield1;
}
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
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/")));
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);
}
}
}
}
[...]
}
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>');
[...]
$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');
});
$dom = new IvoPetkov\HTML5DOMDocument();
$dom->loadHTML('<!DOCTYPE html><html><body><h1>Hello</h1><div class="content">This is some text</div></body></html>');
echo $dom->querySelector('h1')->innerHTML;
<pre><?php
include "ScarletsQuery.php";
// Load the HTML content and parse it
$html = file_get_contents('https://www.lipsum.com');
$dom = Scarlets\Library\MarkupLanguage::parseText($html);
// Select meta tag on the HTML header
$description = $dom->selector('head meta[name="description"]')[0];
// Get 'content' attribute value from meta tag
print_r($description->attr('content'));
$description = $dom->selector('#Content p');
// Get element array
print_r($description->view);
$xml='http://www.example.com/rss.xml';
$rss = simplexml_load_string($xml);
$i = 0;
foreach ($rss->channel->item as $feedItem) {
$i++;
echo $title=$feedItem->title;
echo '<br>';
echo $link=$feedItem->link;
echo '<br>';
if($feedItem->description !='') {
$des=$feedItem->description;
} else {
$des='';
}
echo $des;
echo '<br>';
if($i>5) break;
}