• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

使用DiDOM使用PHP解析HTML

在本教程中,我们将学习一个名为Didom的快速、易于使用的 html 解析器。我们将从安装过程开始,然后学习如何使用标签、类等不同类型的选择器从网页上的不同元素中提取信息。

安装使用

您可以通过运行以下命令轻松地在项目目录中安装 Didom :

composer require imangazaliev/didom

运行上述命令后,您将能够从字符串、本地文件或网页加载 HTML。这是一个例子:

require_once('vendor/autoload.php');

use DiDom\Document;

$document = new Document($washington_dc_html_string);

$document = new Document('washington_dc.html', true);

$url = 'https://en.wikipedia.org/wiki/Washington,_D.C.';
$document = new Document($url, true);

当您决定从文档中解析 HTML 时,它可能已经被加载并存储在一个变量中。在这种情况下,您可以简单地将该变量传递给Document()DiDOM 将准备字符串进行解析。

如果必须从文件或 URL 加载 HTML,您可以将其作为第一个参数传递给Document()并将第二个参数设置为true.

您也可以不带任何参数Document使用创建新对象。new Document()在这种情况下,您可以调用该方法loadHtml()从字符串loadHtmlFile()加载 HTML 并从文件或网页加载 HTML。

查找 HTML 元素

在从元素中获取 HTML 或文本之前,您要做的第一件事就是找到元素本身。最简单的方法是简单地使用该find()方法并将所需元素的css选择器作为第一个参数传递。

您还可以将元素的 XPath 作为find()方法的第一个参数传递。Query::TYPE_XPATH但是,这需要您作为第二个参数传递。

如果您只想使用 XPath 值来查找 HTML 元素,您可以简单地使用该xpath()方法而不是每次都Query::TYPE_XPATH作为第二个参数传递。find()

如果 DiDOM 可以找到与传递的 css 选择器或 XPATH 表达式匹配的元素,它将返回DiDom\Element. 如果没有找到这样的元素,它将返回一个空数组。

由于这些方法返回一个数组,因此您可以使用 直接访问第 n 个匹配元素find()[n-1]。

一个例子

在以下示例中,我们将从有关华盛顿特区的 Wikipedia 文章中的所有第一级和第二级标题中获取内部 HTML

require_once('vendor/autoload.php');

use DiDom\Document;

$document = new Document('https://en.wikipedia.org/wiki/Washington,_D.C.', true);

$main_heading = $document->find('h1.firstHeading')[0];
echo $main_heading->html();

$sub_headings = $document->find('h2');

foreach($sub_headings as $sub_heading) {
    if($sub_heading->text() !== 'See also') {
        echo $sub_heading->html();
    } else {
        break;
    }
}

我们首先通过传递有关华盛顿特区的维基百科文章的 URL 创建一个新的 Document 对象。之后,我们使用该find()方法获取主标题元素并将其存储在一个名为 的变量$main_heading中。我们现在可以在这个元素上调用不同的方法,比如text(), innerHtml(),html()等。

对于主标题,我们只调用 html()返回整个标题元素的 HTML 的方法。innerHtml()同样,我们可以使用该方法获取特定元素内的 HTML 。有时,您会对元素的纯文本内容而不是其 HTML 更感兴趣。在这种情况下,您可以简单地使用该text()方法并完成它。

二级标题将我们的维基百科页面划分为明确定义的部分。但是,您可能希望去掉其中的一些子标题,例如“另请参阅”、“注释”等。

一种方法是遍历所有二级标题并检查该text()方法返回的值。如果返回的标题文本是“另见”,我们会跳出循环。

$document->find('h2')[3]您可以分别使用和直接进入第 4 级或第 6 级二级标题$document->find('h2')[5]。

向上和向下遍历 DOM

一旦您可以访问特定元素,该库允许您上下遍历 DOM 树以轻松访问其他元素。

parent()您可以使用该方法转到 HTML 元素的父级。nextSibling()同样,您可以使用andpreviousSibling()方法获取元素的下一个或上一个兄弟元素。

还有很多方法可以用来访问 DOM 元素的子元素。例如,您可以使用该child(n)方法访问特定的子元素。同样,您可以使用firstChild()andlastChild()方法访问特定元素的第一个或最后一个子元素。您可以使用该方法遍历特定 DOM 元素的所有子元素children()。

到达特定元素后,您将能够使用 、 和 方法访问其html()HTMLinnerHtml()等text()。

在下面的示例中,我们从二级标题元素开始,并继续检查下一个兄弟元素是否包含一些文本。一旦我们找到带有一些文本的兄弟元素,我们就会将其输出到浏览器。

require_once('vendor/autoload.php');

use DiDom\Document;

$document = new Document('https://en.wikipedia.org/wiki/Washington,_D.C.', true);

$sub_headings = $document->find('h2');

for($i = 1; $i < count($sub_headings); $i++) {
    if($sub_headings[$i]->text() !== 'See also') {
        $next_sibling = $sub_headings[$i]->nextSibling();
        while(!$next_elem->html()) {
            $next_sibling = $next_sibling->nextSibling();
        }

        echo $next_elem->html()."<br>";
    } else {
        break;
    }
}

您可以使用类似的技术来遍历所有同级元素,并且仅在文本包含特定字符串或同级元素是段落标记等时才输出文本。一旦您了解了基础知识,就很容易找到正确的信息。

操作元素属性

在某些情况下,获取或设置不同元素的属性值的能力可能非常有用。例如 ,我们可以使用. 以类似的方式,您可以获取文档中所有a标签的href属性值。$image_elem->attr('src')

有三种方法可以获取 HTML 元素的给定属性的值。您可以使用该getAttribute('attrName')方法并将您感兴趣的属性的名称作为参数传递。您也可以使用该attr('attrName')方法,其工作原理与getAttribute(). 最后,该库还允许您使用 直接获取属性值$elem->attrName。这意味着您可以 通过使用 直接获取图像元素的src$imageElem->src属性的值。

require_once('vendor/autoload.php');

use DiDom\Document;

$document = new Document('https://en.wikipedia.org/wiki/Washington,_D.C.', true);

$images = $document->find('img');

foreach($images as $image) {
    echo $image->src."<br>";
}

一旦您可以访问src属性,您就可以编写代码来自动下载所有图像文件。这样,您将能够节省大量时间。

您还可以使用三种不同的技术设置给定属性的值。首先,您可以使用setAttribute('attrName', 'attrValue')方法来设置属性值。您也可以使用该attr('attrName', 'attrValue')方法来设置属性值。最后,您可以使用 为给定元素设置属性值$Elem->attrName = 'attrValue'。

添加、删除和替换元素

您还可以使用库提供的不同方法更改加载的 HTML 文档。例如,您可以使用 、 和 方法从 DOM 树中添加、替换或删除元素。appendChild()replace()remove()

该库还允许您创建自己的 HTML 元素,以便将它们附加到原始 HTML 文档中。您可以使用创建一个新的 Element 对象new Element('tagName', 'tagContent')。

请记住, 如果您的程序在实例化元素对象之前不包含该行,您将收到Uncaught Error: Class 'Element' not found错误。use DiDom\Element

获得元素后,您可以使用该方法将其附加到 DOM 中的其他元素,appendChild()也可以使用该replace()方法使用新实例化的元素作为文档中某些旧 HTML 元素的替换。下面的例子应该有助于进一步阐明这个概念。

require_once('vendor/autoload.php');

use DiDom\Document;
use DiDom\Element;

$document = new Document('https://en.wikipedia.org/wiki/Washington,_D.C.', true);

// This will result in error.
echo $document->find('h2.test-heading')[0]->html()."\n";

$test_heading = new Element('h2', 'This is test heading.');
$test_heading->class = 'test-heading';

$document->find('h1')[0]->replace($test_heading);

echo $document->find('h2.test-heading')[0]->html()."\n";

最初,我们的文档中没有带有test-heading类的h2元素。因此,如果我们尝试访问这样的元素,我们将不断收到错误消息。

在验证不存在这样的元素后,我们创建一个新的h2元素并将其class属性的值更改为test-heading。

之后,我们将文档中的第一个h1元素替换为新创建的h2元素。再次使用find()我们文档上的方法来查找带有类test-heading的h2标题现在将返回一个元素。

最后的想法

本教程介绍了 PHP DiDOM HTML 解析器的基础知识。我们从安装开始,然后学习了如何从字符串、文件或 URL 加载 HTML。之后,我们讨论了如何根据其 CSS 选择器或 XPath 查找特定元素。我们还学习了如何获取元素的兄弟姐妹、父级或子级。其余部分介绍了我们如何操作特定元素的属性或添加、删除和替换 HTML 文档中的元素。


文章目录
  • 安装使用
  • 查找 HTML 元素
    • 一个例子
  • 向上和向下遍历 DOM
  • 操作元素属性
  • 添加、删除和替换元素
  • 最后的想法