让 PHP 像 Jquery 一样操作 DOM!
本文档由 icy2003 根据 官方文档 翻译而成,于 2019-01-23 创建,只限于 www.icy2003.com 发布
描述、要求和特性
-
用 PHP5 写的 HTML DOM 解析器,可以让你轻松操作 HTML
-
要求 PHP5+
-
支持非法 HTML
-
就像 JQuery 一样在 HTML 页面用选择器查找标签
-
简单一句话就可以提取 HTML 内容
下载和文档
-
从 Sourceforge 下载最新版本
快速开始
获取 HTML 元素
// 从文件或者链接 创建 DOM 节点
$html = file_get_html('http://www.google.com/');
// 查找所有图片
foreach($html->find('img') as $element) echo $element->src . '<br>';
// 查找所有链接
foreach($html->find('a') as $element) echo $element->href . '<br>';
修改 HTML 元素
// 从字符串创建 DOM 节点
$html = str_get_html('<div id="hello">Hello</div><div id="world">World</div>');
$html->find('div', 1)->class = 'bar';
$html->find('div[id=hello]', 0)->innertext = 'foo';
echo $html; // 输出: <div id="hello">foo</div><div id="world" class="bar">World</div>
提取 HTML 内容
// 从 HTML 中打印内容(不带标签)
echo file_get_html('http://www.google.com/')->plaintext;
划重点!
// 从 URL 创建 DOM
$html = file_get_html('http://slashdot.org/');
// 查找所有的 article 块
foreach($html->find('div.article') as $article) {
$item['title'] = $article->find('div.title', 0)->plaintext;
$item['intro'] = $article->find('div.intro', 0)->plaintext;
$item['details'] = $article->find('div.details', 0)->plaintext;
$articles[] = $item;
}
print_r($articles);
如何创建 HTML DOM 对象
快速访问
// 从字符串创建 DOM 对象
$html = str_get_html('<html><body>Hello!</body></html>');
// 从 URL 创建 DOM 对象
$html = file_get_html('http://www.google.com/');
// 从一个 HTML 文件创建 DOM 对象
$html = file_get_html('test.htm');
面向对象方式
// 创建 DOM 对象
$html = new simple_html_dom();
// 从字符串加载 HTML
$html->load('<html><body>Hello!</body></html>');
// 从 URL 加载 HTML
$html->load_file('http://www.google.com/');
// 从 HTML 文件加载 HTML
$html->load_file('test.htm');
如何查找 HTML 元素
基础
// 查找所有的 a 链接,返回元素对象的数组
$ret = $html->find('a');
// 查找第 N 个 a 链接,返回元素对象,如果找不到则返回 null(从零开始)
$ret = $html->find('a', 0);
// 查找最后一个 a 链接,返回元素对象,如果找不到则返回 null(从零开始)
$ret = $html->find('a', -1);
// 根据 id 属性查找所有的 <div>
$ret = $html->find('div[id]');
// 根据 id 为 foo 的属性查找所有的 <div>
$ret = $html->find('div[id=foo]');
高级
// 查找 id 等于 foo 的所有元素
$ret = $html->find('#foo');
// 查找 class 等于 foo 的所有元素
$ret = $html->find('.foo');
// 查找所有包含 id 属性的元素
$ret = $html->find('*[id]');
// 查找 a 链接和图片
$ret = $html->find('a, img');
// 查找所有包含 title 属性的 a 链接和图片
$ret = $html->find('a[title], img[title]');
子选择器
// 查找所有在 <ul> 里的 <li>
$es = $html->find('ul li');
// 查找嵌套的 <div> 标签
$es = $html->find('div div div');
// 在 <table> 里查找所有 class 等于 hello 的 <td>
$es = $html->find('table.hello td');
// 在 table 标签里查找所有属性 align 等于 center 的 td 标签
$es = $html->find(''table td[align=center]');
嵌套选择器
// 在 <ul> 查找所有的 <li>
foreach($html->find('ul') as $ul)
{
foreach($ul->find('li') as $li)
{
// do something...
}
}
// 在第一个 <ul> 里查找第一个 <li>
$e = $html->find('ul', 0)->find('li', 0);
属性过滤器
在属性选择器中支持这些运算符:
过滤器 | 描述 |
---|---|
[attribute] | 匹配具有指定属性的元素 |
[!attribute] | 匹配没有指定属性的元素 |
[attribute=value] | 将具有指定属性的元素与特定值匹配 |
[attribute!=value] | 将没有指定属性的元素与特定值匹配 |
[attribute^=value] | 匹配具有指定属性且以特定值开头的元素 |
[attribute$=value] | 匹配具有指定属性且以特定值结尾的元素 |
[attribute*=value] | 匹配具有指定属性且包含特定值的元素 |
文本和注释
// 查找所有的文本块
$es = $html->find('text');
// 查找所有注释块(<!--...-->)
$es = $html->find('comment');
如何访问 HTML 元素的属性
获取、设置和删除属性
// 获取一个属性(如果该属性是非值属性(如选中、选中…),它将返回 true 或 false)
$value = $e->href;
// 设置一个属性(如果该属性是非值属性(如选中、选中…),则将其值设置为 true 或 false)
$e->href = 'my link';
// 移除属性,将其值设置为 null!
$e->href = null;
// 确定属性是否存在?
if(isset($e->href)) echo 'href exist!';
魔术属性
// 举例
$html = str_get_html("<div>foo <b>bar</b></div>");
$e = $html->find("div", 0);
echo $e->tag; // 返回: " div"
echo $e->outertext; // 返回: " <div>foo <b>bar</b></div>"
echo $e->innertext; // 返回: " foo <b>bar</b>"
echo $e->plaintext; // 返回: " foo bar"
属性名 | 用法 |
---|---|
$e->tag | 读取或写入元素的标签名 |
$e->outertext | 读取或写入元素的外部 HTML 文本 |
$e->innertext | 读取或写入元素的内部 HTML 文本 |
$e->plaintext | 读取或写入元素的纯文本 |
小技巧
// 从 HTML 提取内容
echo $html->plaintext;
// 包裹元素
$e->outertext = '<div class="wrap">' . $e->outertext . '<div>';
// 移除元素,将其 outerText 设置为空字符串
$e->outertext = '';
// 附加元素
$e->outertext = $e->outertext . '<div>foo<div>';
// 插入元素
$e->outertext = '<div>foo<div>' . $e->outertext;
如何访问 DOM 节点树
背景知识
如果您不太熟悉HTML DOM,请检查此链接以了解更多信息……
// 例子
echo $html->find("#div1", 0)->children(1)->children(1)->children(2)->id;
// 或者
echo $html->getElementById("div1")->childNodes(1)->childNodes(1)->childNodes(2)->getAttribute('id');
链式节点
还可以使用驼峰命名转换调用方法
方法 | 描述 |
---|---|
mixed $e->children( [int $index] ) | 如果设置了索引,则返回第 N 个子对象,否则返回子对象数组 |
element $e->parent() | 返回元素的父级 |
element $e->first_child() | 返回元素的第一个子元素,如果找不到,则返回 null |
element $e->last_child() | 返回元素的最后一个子元素,如果找不到,则返回 null |
element $e->next_sibling() | 返回元素的下一个同级,如果找不到,则返回 null |
element $e->prev_sibling() | 返回元素的上一个同级,如果找不到,则返回 null |
如何打印 DOM 对象的内容
快速访问
// 将内部 DOM 树转储回字符串
$str = $html;
// 打印!
echo $html;
面向对象方式
// 将内部 DOM 树转储回字符串
$str = $html->save();
// 将内部 DOM 树转储回文件
$html->save('result.htm');
如何自定义解析行为
回调函数
// 编写带参数 "$element" 的函数
function my_callback($element) {
// 隐藏所有的 <b> 标签
if ($element->tag=='b') $element->outertext = '';
}
// 用函数名注册回调函数
$html->set_callback('my_callback');
// 转储时将调用回调函数
echo $html;
API 参考
API 参考
帮助函数
名字 | 描述 |
---|---|
object str_get_html( string $content ) | 从字符串创建 DOM 对象 |
object file_get_html( string $filename ) | 从文件或 URL 创建 DOM 对象 |
DOM 方法和属性
名字 | 描述 |
---|---|
void __construct( [string $filename] ) | 构造函数,设置文件名参数将自动加载内容,无论是文本还是文件/url |
string plaintext | 返回从 HTML 提取的内容 |
void clear() | 清除内存 |
void load( string $content ) | 从字符串加载内容 |
string save( [string $filename] ) | 将内部 DOM 树转储回字符串。如果设置了 $filename,结果字符串将保存到文件 |
void load_file( string $filename ) | 从文件或 URL 加载内容 |
void set_callback( string $function_name ) | 设置回调函数 |
mixed find( string $selector [, int $index] ) | 查找元素的 CSS 选择器。如果设置了索引,则返回对应第 N 个元素,否则返回对象数组 |
元素方法和属性
名字 | 描述 |
---|---|
string[attribute] | 读取或写入元素的属性值 |
string tag | 读取或写入元素的标签名 |
string outertext | 读取或写入元素的外部 HTML 文本 |
string innertext | 读取或写入元素的内部 HTML 文本 |
string plaintext | 读取或写入元素的纯文本 |
mixed find( string $selector [, int $index] ) | 通过选择器找子元素。如果设置了 索引,则返回对应第 N 个元素,否则返回对象数组 |
节点链式
名字 | 描述 |
---|---|
mixed $e->children( [int $index] ) | 如果设置了索引,则返回第 N 个子对象,否则返回子对象数组 |
element $e->parent() | 返回元素的父级 |
element $e->first_child() | 返回元素的第一个子元素,如果找不到,则返回 null |
element $e->last_child() | 返回元素的最后一个子元素,如果找不到,则返回 null |
element $e->next_sibling() | 返回元素的下一个同级,如果找不到,则返回 null |
element $e->prev_sibling() | 返回元素的上一个同级,如果找不到,则返回 null |
骆驼命名转换
还可以使用 W3C 标准的驼峰命名转换调用方法
方法 | 映射 |
---|---|
array $e->getAllAttributes() | array $e->attr |
string $e->getAttribute( $name ) | string $e->attribute |
void $e->setAttribute( $name, $value ) | void $value = $e->attribute |
bool $e->hasAttribute( $name ) | bool isset($e->attribute) |
void $e->removeAttribute( $name ) | void $e->attribute = null |
element $e->getElementById( $id ) | mixed $e->find( "#$id", 0 ) |
mixed $e->getElementsById( $id [,$index] ) | mixed $e->find( "#$id" [, int $index] ) |
element $e->getElementByTagName($name ) | mixed $e->find( $name, 0 ) |
mixed $e->getElementsByTagName( $name [, $index] ) | mixed $e->find( $name [, int $index] ) |
element $e->parentNode() | element $e->parent() |
mixed $e->childNodes( [$index] ) | mixed $e->children( [int $index] ) |
element $e->firstChild() | element $e->first_child() |
element $e->nextSibling() | element $e->next_sibling() |
element $e->previousSibling() | element $e->prev_sibling() |