ee01 / php-html-parser
HTML DOM 解析器。它允许您操作 HTML。使用选择器查找 HTML 页面上的标签,就像 jQuery 一样。
Requires
- php: >=7.1
- ext-mbstring: *
- paquettg/string-encode: ~1.0.0
Requires (Dev)
- mockery/mockery: ^1.2
- php-coveralls/php-coveralls: ^2.1
- phpunit/phpunit: ^7.5.1
README
版本 2.0.2.1
PHPHtmlParser 是一个简单、灵活的 HTML 解析器,允许您使用任何 CSS 选择器选择标签,就像 jQuery 一样。目标是协助开发需要快速、简单抓取 HTML(无论是有效的还是无效的)的工具!
安装
此包可在 packagist 上找到,并建议使用 composer 加载。我们支持 php 7.1、7.2 和 7.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,这是一个在线找到的实时页面,并处理所有内容-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
使用 php cURL 配置,包括更改到 POST 方法。
// load via post method $dom_login->load('http://google.com/login', [ 'curl' => [ CURLOPT_REFERER => 'http://google.com', CURLOPT_HTTPHEADER => [ 'Content-Type: application/json;', ], CURLOPT_POST => 1, CURLOPT_POSTFIELDS => [ 'account' => '111' ] ] ]); $html = $dom->outerHtml;
使 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.
目前我们支持 8 个选项。
严格
严格模式,默认为false,如果发现HTML不符合严格规范(所有标签必须有结束标签,没有值的属性等),则会抛出StrickException异常。
whitespaceTextNode
whitespaceTextNode,默认为true,选项告诉解析器即使节点内容为空(只有空白字符)也要保存文本节点。将其设置为false将忽略文档中找到的所有仅包含空白字符的文本节点。
enforceEncoding
enforceEncoding,默认为null,选项将强制使用字符集来读取内容并在该编码中返回内容。将其设置为null将尝试从给定的字符串内容中推断编码。
cleanupInput
将此设置为false以跳过解析器的整个清理阶段。如果设置为true,则将忽略下一个3个选项。默认为true。
removeScripts
将此设置为false以跳过从文档主体中删除脚本标签。这可能会产生不利影响。默认为true。
removeStyles
将此设置为false以跳过从文档主体中删除样式标签。这可能会产生不利影响。默认为true。
preserveLineBreaks
如果设置为true,则保留换行符。如果设置为false,则将换行符作为输入清理过程的一部分进行清理。默认为false。
removeDoubleSpace
如果您想保留文本节点内的空白字符,请将此设置为false。它默认设置为true。静态外观
您还可以为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>');
您可以轻松地修改TextNode对象的文本。请注意,如果您设置了编码,则新文本将使用现有编码进行编码。
$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->firstChild()->setText('biz baz'); echo $dom; // '<div class="all"><p>Hey bro, <a href="google.com">biz baz</a><br /> :)</p></div>'