gfd6th/php-html-parser

HTML DOM解析器。它允许您操作HTML。使用选择器在HTML页面中查找标签,就像jQuery一样。

1.8.1 2018-08-26 09:29 UTC

This package is auto-updated.

Last update: 2024-09-26 16:54:59 UTC


README

注意:这是paquettg/php-html-parser的分支。项目仅处于被动维护状态。接受拉取请求。如果您愿意维护此包,请创建一个问题并让我们知道。

Build Status Coverage Status Scrutinizer Code Quality

PHPHtmlParser是一个简单、灵活的HTML解析器,允许您使用任何CSS选择器选择标签,就像jQuery一样。目标是帮助开发需要快速、轻松地抓取HTML的工具,无论它是有效还是无效!该项目最初由sunra/php-simple-html-dom-parser支持,但支持似乎已经停止,因此该项目是我对他之前工作的改编。

安装

此包可在packagist上找到,并且最好使用composer加载。我们支持php 5.6、7.0和hhvm 2.3。

用法

您可以在测试目录中找到许多如何使用DOM解析器及其任何部分(您可能永远不会接触)的示例。测试使用PHPUnit进行,非常小,每个只有几行,是一个很好的开始地方。鉴于此,我仍然会展示一些如何使用该包的示例。以下是一个使用该包的非常简单的示例。

// Assuming you installed from Composer:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->load('<div class="all"><p>Hey bro, <a href="google.com">click here</a><br /> :)</p></div>');
$a = $dom->find('a')[0];
echo $a->text; // "click here"

上面的示例将输出"点击这里"。简单吗?从DOM中获取相同结果的方式有很多,比如$dom->getElementsbyTag('a')[0]$dom->find('a', 0),这些都可以在测试或代码本身中找到。

加载文件

您还可以无缝地将文件加载到DOM中,而不是字符串,这更方便,这也是大多数开发者加载HTML的方式。以下示例来自我们的测试,并使用了其中找到的"big.html"文件。

// Assuming you installed from Composer:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadFromFile('tests/big.html');
$contents = $dom->find('.content-border');
echo count($contents); // 10

foreach ($contents as $content)
{
	// get the class attr
	$class = $content->getAttribute('class');
	
	// do something with the html
	$html = $content->innerHtml;

	// or refine the find some more
	$child   = $content->firstChild();
	$sibling = $child->nextSibling();
}

此示例加载了来自big.html的HTML,这是一个在线找到的真正页面,并获取了所有content-border类以进行处理。它还展示了您可以使用节点做一些事情,但这并不是节点可用的方法列表的详尽列表。

或者,您始终可以使用load()方法加载文件。它将尝试使用file_exists查找文件,如果成功,将为您调用loadFromFile()。同样适用于URL和loadFromUrl()方法。

加载URL

加载URL的方式与从文件加载HTML的方式非常相似。

// Assuming you installed from Composer:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadFromUrl('http://google.com');
$html = $dom->outerHtml;

// or
$dom->load('http://google.com');
$html = $dom->outerHtml; // same result as the first example

loadFromUrl方法的特别之处在于PHPHtmlParser\CurlInterface参数,一个可选的第二个参数。默认情况下,我们使用PHPHtmlParser\Curl类来获取URL的内容。另一方面,您可以注入自己的CurlInterface实现,我们将尝试使用您想要的任何工具/设置来加载URL。

// Assuming you installed from Composer:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;
use App\Services\Connector;

$dom = new Dom;
$dom->loadFromUrl('http://google.com', [], new Connector);
$html = $dom->outerHtml;

只要连接器对象正确实现了PHPHtmlParser\CurlInterface接口,它就会使用该对象来获取URL的内容,而不是默认的PHPHtmlParser\Curl类。

加载字符串

直接加载字符串,而不是在load()中进行检查,也很容易完成。

// Assuming you installed from Composer:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadStr('<html>String</html>', []);
$html = $dom->outerHtml;

如果字符串太长,根据您的文件系统,load() 方法将抛出警告。如果发生这种情况,您只需调用上述方法即可绕过 load() 方法中的 is_file() 检查。

选项

您还可以设置影响解析器行为的解析选项。您可以使用 Dom 对象中的 setOptions 方法设置全局选项数组,或者将特定实例的选项作为额外(可选)参数添加到 load 方法中。

// Assuming you installed from Composer:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->setOptions([
	'strict' => true, // Set a global option to enable strict html parsing.
]);

$dom->load('http://google.com', [
	'whitespaceTextNode' => false, // Only applies to this load.
]);

$dom->load('http://gmail.com'); // will not have whitespaceTextNode set to false.

目前我们支持 7 个选项。

严格

默认情况下为 false 的 strict 将在发现 html 不符合严格规范(所有标签必须有闭合标签,没有值的属性等)时抛出 StrickException

whitespaceTextNode

默认为 true 的 whitespaceTextNode 选项告诉解析器保存文本节点,即使节点的内容为空(只有空白)。将其设置为 false 将忽略文档中找到的所有仅包含空白的文本节点。

enforceEncoding

默认为 null 的 enforceEncoding 选项将强制使用字符集来读取内容并在该编码中返回内容。将其设置为 null 将触发从提供的字符串内容中尝试确定编码。

cleanupInput

将此设置为 true 以跳过解析器的整个清理阶段。如果设置为 true,则将忽略下一个 3 个选项。默认为 false

removeScripts

将此设置为 false 以跳过从文档体中移除脚本标签。这可能会产生不利影响。默认为 true

removeStyles

将此设置为 false 以跳过从文档体中移除样式标签。这可能会产生不利影响。默认为 true

preserveLineBreaks

如果设置为 true,则保留换行符。如果设置为 false,则在输入清理过程中将清理换行符。默认为 false

静态外观

您还可以为 Dom 对象安装静态外观。

PHPHtmlParser\StaticDom::mount();

Dom::load('tests/big.hmtl');
$objects = Dom::find('.content-border');

上面的 PHP 块与第一个示例执行相同的查找和加载,但它使用的是静态外观,该外观支持 Dom 对象中找到的所有公共方法。

修改 Dom

您可以始终修改从任何加载方法创建的 dom。要更改任何节点的属性,只需调用 setAttribute 方法。

$dom = new Dom;
$dom->load('<div class="all"><p>Hey bro, <a href="google.com">click here</a><br /> :)</p></div>');
$a = $dom->find('a')[0];
$a->setAttribute('class', 'foo');
echo $a->getAttribute('class'); // "foo"

您还可以直接获取 PHPHtmlParser\Dom\Tag 类并按需操作它。

$dom = new Dom;
$dom->load('<div class="all"><p>Hey bro, <a href="google.com">click here</a><br /> :)</p></div>');
$a   = $dom->find('a')[0];
$tag = $a->getTag();
$tag->setAttribute('class', 'foo');
echo $a->getAttribute('class'); // "foo"

您还可以从树中删除节点。只需在任意节点上调用 delete 方法即可将其从树中删除。请注意,您应在从 `DOM` 中删除节点后取消设置该节点,否则它将占用内存,直到取消设置。

$dom = new Dom;
$dom->load('<div class="all"><p>Hey bro, <a href="google.com">click here</a><br /> :)</p></div>');
$a   = $dom->find('a')[0];
$a->delete();
unset($a);
echo $dom; // '<div class="all"><p>Hey bro, <br /> :)</p></div>');