thesoftwarefanatics / php-html-parser
HTML DOM解析器。允许您操作HTML。使用选择器查找HTML页面上的标签,就像jQuery一样。
Requires
- php: ^7.1
- paquettg/string-encode: ^0.1.1
Requires (Dev)
- mockery/mockery: ^1.0
- php-coveralls/php-coveralls: ^2.0
- phpunit/phpunit: ^6.5
Replaces
- paquettg/php-html-parser: 1.8.1
README
注意:这是一个paquettg/php-html-parser的分支,当时由于原始项目不支持PHP 7.2,因此需要提供兼容性。从那时起,原始作者已经重新开始处理该包,因此您应该使用那个而不是这个。
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;
只要Connector对象正确实现了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个选项。
严格
默认情况下,严格(Strict)为false,如果它发现HTML不严格符合规范(所有标签都必须有闭合标签,没有值的属性等),则将抛出StrickException
异常。
空白文本节点
空白文本节点(whitespaceTextNode)选项默认为true,它告诉解析器即使节点的内容为空(只有空白)也要保存文本节点。将其设置为false将忽略文档中找到的所有仅包含空白的文本节点。
强制编码
强制编码(enforceEncoding)选项默认为null,它将强制使用一个字符集来读取内容并以该编码返回内容。将其设置为null将触发尝试从提供的字符串内容中确定编码。
清理输入
将此设置为true
以跳过解析器的整个清理阶段。如果设置为true,则将忽略以下3个选项。默认为false
。
删除脚本
将此设置为false
以跳过从文档主体中删除脚本标签。这可能会产生不利影响。默认为true
。
删除样式
将此设置为false
以跳过从文档主体中删除样式标签。这可能会产生不利影响。默认为true
。
保留换行符
如果设置为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>');