PHP类库DomDocument类

最近帮朋友采集点数据,因为之前也采集过小说、bt链接这种。所以感觉问题不大,上手就写。

之前用的最多的大多是SimpleHtmlDom或者phpQuery之类的老工具了(工具虽老但用着顺手啊哈哈)

这次为了上手快用的TP5.1在跑,但是如何引用SimpleHtmlDom就有些麻烦了。因为TP5.1的自动加载机制是根据命名空间和文件命名来加载的,但是SimpleHtmlDom这个单文件中封装了2个类就有些麻烦了。

其实如果只是获取页面内容,靠curl和file_get_contents也能拿到链接。只是DOM树解析这块有些棘手。

那么问题来了,PHP有自带的DOM解析库么?

没错,我在PHP手册中找到了内置的DOM操作库。传送门

因为我用的XPath抓取的,所以也引用了DOMXPATH类。

这里放一下自己封的两个函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
* 获取一个DOMXPath实例
* @param string $htmlCode 页面源码
*/
function getDomXPath($htmlCode){
// 阻止因为页面元素不规范引起的报错
$libxml_previous_state = libxml_use_internal_errors(true);

$dom = new \DOMDocument();
$dom->loadHTML($htmlCode);

// 阻止因为页面元素不规范引起的报错
libxml_clear_errors();
libxml_use_internal_errors($libxml_previous_state);

$xpath = new \DOMXPath($dom);

return $xpath;
}

/**
* 使用xpath表达式获取值 默认返回对象
* @param \DOMXPath $xpath xpath实例
* @param string $xPathExp xpath表达式
* @param bool $all 是否匹配多个对象
* @return object|null
*/
function getValueByXPath(\DOMXPath &$xpath,$xPathExp,$all = false){
$node = $xpath->query($xPathExp);
if($node->length > 0){
if($all){
$nodeValue = [];
foreach ($node as $childNode){
$nodeValue[] = $childNode;
}
return $nodeValue;
}else{
return $node[0];
}
}else{
throw new Exception($xPathExp.' 未匹配到内容!');
}
}

//demo
$item = [];
$xPath = $this->getDomXPath($htmlCode);
$item['title'] = $this->getValueByXPath($xpath,'/html/body/div[9]/h1')->nodeValue;
...

因为有些html的代码格式(or xml格式)不标准,会导致DOMDocument的loadHTML()方法报错,解决方法是在开头和结尾加上这三行屏蔽错误的代码。参考:PHP: 禁止 DomDocument::loadHTML() 对不规范的HTML输出警告信息

1
2
3
4
5
6
7
8
// 阻止因为页面元素不规范引起的报错
$libxml_previous_state = libxml_use_internal_errors(true);

code...

// 阻止因为页面元素不规范引起的报错
libxml_clear_errors();
libxml_use_internal_errors($libxml_previous_state);

评论区