PHP HTML解析器

PHPHtmlParser是一款简单灵活的HTML解析器,允许您使用任何CSS选择器来选取标签,类似于jQuery的方式。其目标是为那些需要快速简便地抓取HTML(无论是否合法)的工具提供帮助!

安装 通过Composer安装最新版本。

$ composer require paquettg/php-html-parser

本包可在Packagist上找到,并推荐通过Composer加载。我们支持PHP 7.2、7.3和7.4。

基本用法 在测试目录中,您可以找到关于如何使用DOM解析器及其各部分(很可能您永远不会直接触碰)的许多示例。这些测试使用PHPUnit编写,非常简短,每个只有几行,是开始学习的好地方。即便如此,我仍会展示一些如何使用该包的基本例子。以下是一个非常简单的使用示例:

// 假设您已通过Composer安装:

require "vendor/autoload.php";
use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadStr('

嘿,兄弟,点击这里
:)

'); $a = $dom->find('a')[0]; echo $a->text; // 输出 "点击这里"

这段代码将输出“点击这里”。简单吧?从DOM获取相同结果的方式有很多种,比如$dom->getElementsByTagName(‘a’)[0]或$dom->find(‘a’, 0),更多用法可参考测试案例或源码本身。

支持PHP Html Parser的资金赞助 获取受支持的Monolog,并通过Tidelift订阅资助该项目。

Tidelift为您的应用所依赖的开源依赖项提供了商业级别的支持与维护。节省时间,降低风险,改善代码健康状况,同时支持您实际使用的依赖项的维护者。

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

// 假设您已通过Composer安装:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;

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

foreach ($contents as $content) {
    // 获取类属性
    $class = $content->getAttribute('class');

    // 对HTML进行处理
    $html = $content->innerHtml;

    // 或进一步细化查找
    $child   = $content->firstChild();
    $sibling = $child->nextSibling();
}

此例从”big.html”(一个真实的在线页面)加载HTML,获取所有.content-border类以进行处理,并展示了可以对节点执行的一些操作,但并非节点可用方法的完整列表。

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

// 假设您已通过Composer安装:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;

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

// 或者

$dom->loadFromUrl('http://google.com');
$html = $dom->outerHtml; // 结果与第一个示例相同
默认情况下,loadFromUrl使用\Psr\Http\Client\ClientInterface的一个实现来执行HTTP请求,并使用一个默认的\Psr\Http\Message\RequestInterface实现来构造请求体。您可以轻松实现自己的客户端或请求版本,以便在使用loadFromUrl时使用自定义的HTTP连接。

// 假设您已通过Composer安装:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;
use App\Services\MyClient;

$dom = new Dom;
$dom->loadFromUrl('http://google.com', null, new MyClient());
$html = $dom->outerHtml;
只要客户端对象正确实现了接口,它就会使用那个对象来获取URL的内容。

加载字符串 直接加载字符串也非常简单。

// 假设您已通过Composer安装:

require "vendor/autoload.php";
use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadStr('字符串');
$html = $dom->outerHtml;

配置选项 您还可以设置影响解析引擎行为的解析选项。可以通过Dom对象的setOptions方法设置全局选项数组,或者将选项作为load方法的额外(可选)参数添加来设定实例特定的选项。

// 假设您已通过Composer安装:
require "vendor/autoload.php";
use PHPHtmlParser\Dom;
use PHPHtmlParser\Options;

$dom = new Dom;
$dom->setOptions(
    // 这被设置为全局选项级别。
    (new Options())
        ->setStrict(true)
);

$dom->loadFromUrl('http://google.com', 
    (new Options())->setWhitespaceTextNode(false) // 只在此加载中适用。
);

$dom->loadFromUrl('http://gmail.com'); // 将不会设置whitespaceTextNode为false。

目前,我们支持12个配置选项。

严格模式 默认关闭,当发现HTML不严格合规(所有标签都必须有闭合标签,没有无值属性等)时抛出StrictException。

空白文本节点 默认开启,告诉解析器保存即使是空内容(仅空白字符)的文本节点。设置为假则忽略文档中的所有仅空白文本节点。

强制编码 默认为空,用于指定读取内容和返回内容时使用的字符集。若设为null,则尝试从给定字符串的内容中推断编码。

其余选项还包括清理输入阶段控制(cleanupInput)、移除脚本和样式标签、保留换行符、去除双倍空格、移除Smarty脚本以及HTML特殊字符解码等功能,它们各自都有详细的描述和默认值,使用户能根据需求定制解析过程。

静态外观(Static Facade) 您还可以为 Dom 对象安装一个静态外观。

PHPHtmlParser\StaticDom::mount();

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

上述 PHP 代码块与第一个示例执行相同的操作,但使用了静态外观,该外观支持在 Dom 对象中找到的所有公共方法。

修改 DOM 您可以随时修改通过任何加载方法创建的 DOM。要更改节点的属性,只需调用 setAttribute 方法。

use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadStr('

Hey bro, click here
:)

'); $a = $dom->find('a')[0]; $a->setAttribute('class', 'foo'); echo $a->getAttribute('class'); // "foo"

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

use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadStr('

Hey bro, click here
:)

'); /** @var Dom\Node\AbstractNode $a */ $a = $dom->find('a')[0]; $tag = $a->getTag(); $tag->setAttribute('class', 'foo'); echo $a->getAttribute('class'); // "foo"

也可以从树中删除节点。只需对任何节点调用 delete 方法即可将其从树中移除。重要的是要注意,在从 DOM 中删除节点后应将其取消设置,否则它仍会占用内存。

use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadStr('

Hey bro, click here
:)

'); /** @var Dom\Node\AbstractNode $a */ $a = $dom->find('a')[0]; $a->delete(); unset($a); echo $dom; // '

Hey bro,
:)

';

您可以轻松地修改 TextNode 对象的文本。请注意,如果您设置了编码,新文本将使用现有编码进行编码。

use PHPHtmlParser\Dom;

$dom = new Dom;
$dom->loadStr('

Hey bro, click here
:)

'); /** @var Dom\Node\InnerNode $a */ $a = $dom->find('a')[0]; $a->firstChild()->setText('biz baz'); echo $dom; // '

Hey bro, biz baz
:)

'

留下评论