您现在的位置: 365建站网 > 365文章 > PHP DOM XPath获取HTML节点和出现乱码的解决方法

PHP DOM XPath获取HTML节点和出现乱码的解决方法

文章来源:365jz.com     点击数:1121    更新时间:2018-07-21 09:06   参与评论

PHP的有些技巧可能大家并不常用到,比如DOM相关的对象。

XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。这里讨论的是在XPath语言规范下,封装而成的一种解析XML文档的技术。在PHP,Python里,具体是指xpath这个函数。所以,Wikipedia提到的对XML文档某部分位置的定位,就是用XPath的规范,定位到这个部分,为我所用。我们的目的是解析HTML网页中的元素,将HTML转换成XML文档之后,就是XPath出鞘之时。具体的转换方法,因开发环境而异,后文会附上一些实际工作中遇到的问题。下文所述的xpath()函数均指PHP语言核心函数库中的函数xpath()。

这些方法几乎和Javascript一样的方便,轻松一句就能获取到HTML DOM节点的数据。

相比于使用正则表达式,这个方法更简单快捷。

我就就常用DOMDocument和XPath两个类做一个介绍。

假设有这样一个HTML页面(部分),其内容如下:

</>code

  1. $html = <<<HTML
  2.     <div class="container">
  3.         <img class="logo img" id="img1" src="/images/img1.jpg" />
  4.         <img class="icon img" id="img2" src="/images/img2.jpg" />
  5.         <img class="icon use" id="img3" src="/images/img3.jpg" />
  6.         <p class="icon" id="content">Welcome PHP!</p>
  7.     </div>
  8. HTML;

我们把它赋值给字符串变量$html。

我们将$html加载到DOM对象,再用DOMXPath解析处理。

</>code

  1. $dom = new DOMDocument();
  2. $dom->loadHTML($html);
  3. $xpath = new DOMXPath($dom);

1 DOMXPath用法

接下来我们将用DOMXPath的方法来解析。

DOMXPath有两个核心的部分:传入的表达式和返回值。

2 获取img src

获取第一个图片的src内容:

</>code

  1. echo $src = $xpath->evaluate('string(//img/@src)');/*输出:
  2. /images/img1.jpg
  3. */

获取全部IMG SRC内容

</>code

  1. $nodeList = $xpath->query("//img");
  2. $srcList = [];foreach ($nodeList as $node) {
  3.     $srcList[] = $node->attributes->getNamedItem('src')->nodeValue;
  4. }
  5. print_r($srcList);/*输出:
  6. Array
  7. (
  8.  [0] => /images/img1.jpg
  9.  [1] => /images/img2.jpg
  10.  [2] => /images/img3.jpg
  11. )
  12. */

3 获取特定class DOM

获取所有class等于content的id值,这里class值必须是唯一的:

</>code

  1. $nodeList = $xpath->query('//*[@class="icon"]');
  2. $result = [];foreach ($nodeList as $node) {
  3.     $result[] = $node->attributes->getNamedItem('id')->nodeValue;
  4. }
  5. print_r($result);/*输出:
  6. Array
  7. (
  8.     [0] => content
  9. )
  10. */

获取所有class包含icon的节点的id值:

</>code

  1. $nodeList = $xpath->query('//*[contains(@class, "icon")]');
  2. $result = [];foreach ($nodeList as $node) {
  3.     $result[] = $node->attributes->getNamedItem('id')->nodeValue;
  4. }
  5. print_r($result);/*输出:
  6. Array
  7. (
  8.     [0] => img2
  9.     [1] => img3
  10.     [2] => content
  11. )
  12. */

获取所有class包含icon的节点的完整HTML内容:

</>code

  1. $nodeList = $xpath->query('//*[contains(@class, "icon")]');$result = [];
  2. foreach ($nodeList as $node) {    $result[] = $dom->saveHTML($node);
  3. }
  4. print_r($result);
  5. /*输出:
  6. Array
  7. (
  8.     [0] => <img class="icon img" id="img2" src="/images/img2.jpg">
  9.     [1] => <img class="icon use" id="img3" src="/images/img3.jpg">
  10.     [2] => <p class="icon" id="content">Welcome PHP!</p>
  11. )
  12. */

常用到的:

$element->nodeValue

$element->getElementsByTagName('td')->item(1)->nodeValue

$element->getElementsByTagName('td')->item(5)->getElementsByTagName('a')->item(0)->getAttribute('href')


PHP DOM XPath获取HTML节点出现乱码的解决方法:

</>code

  1. <?php
  2. $doc = new DOMDocument();
  3. $doc->loadHTML('<?xml encoding="UTF-8">' . $html);
  4. // dirty fix
  5. foreach ($doc->childNodes as $item)
  6.     if ($item->nodeType == XML_PI_NODE)
  7.         $doc->removeChild($item); // remove hack
  8. $doc->encoding = 'UTF-8'; // insert proper
  9. ?>


另外解决乱码的方法:

<?php 
    $pageDom 
= new DomDocument();    
    
$searchPage mb_convert_encoding($htmlUTF8Page'HTML-ENTITIES'"UTF-8"); 
    @
$pageDom->loadHTML($searchPage); 

?>


<?php 

//创建一个dom对象并读取xml文件到内存中

$dom = new DOMDocument('1.0','utf-8');

$dom->load('./book.xml');

//创建一个xpath对象

$xpath = new DOMXPATH($dom);

 

$sql = '/bookstore/book[1]/title';//注意此处路径数字从1开始,与下面的item参数不同

 

$rs = $xpath->query($sql);//即使上面定位到了具体某个节点,得到的$rs仍然是一个节点列表

 

print_r($rs);

echo $rs->item(0)->nodeValue;//所以输出的时候仍然得用item(0)->nodeValue 不能直接echo $rs;  另外注意此处item参数从0 开始 ;另外nodeValue的v要大写,不然报错</span>

?>




如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛

发表评论 (1121人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
昵称:
最新评论
------分隔线----------------------------

快速入口

· 365软件
· 杰创官网
· 建站工具
· 网站大全

其它栏目

· 建站教程
· 365学习

业务咨询

· 技术支持
· 服务时间:9:00-18:00
365建站网二维码

Powered by 365建站网 RSS地图 HTML地图

copyright © 2013-2024 版权所有 鄂ICP备17013400号