PHP用DOM方式处理HTML之《Simple HTML DOM》

 更新时间:2016年11月25日 16:54  点击:3683
近经常需要采集一些网上的数据,发现一个PHP处理HTML的利器 simple html dom,看了一下文档,使用非常方便,关键是能够用CSS选择器来访问DOM树,和jquery相似,实在是难得的利器

入门级

simple_html_dom插件
用dom处理html文件的利器
使用:
加载simple_html_dom.php文件

require_once 'simple_html_dom.php'

new simple_html_dom对象

$dom = new simple_html_dom()

加载html

$dom->load($html);

find()方法

$dom->find('div.lookLeftname', 0)->plaintext

class=‘lookLeftname'的div中的纯文本

$dom->find('div.lookLeftname', 0)->innertext

class='lookLeftname'的div中的内部文本

完整测试实例

 代码如下 复制代码

<?php
require_once("simple_html_dom.php");
ini_set('memory_limit','1000M');
ini_set("max_execution_time",6000000);

for($i=1;$i<=21;$i++){
 $html = file_get_html(http://www.111cn.net);
 $as = $html->find('.shopname a');
 $sum = 0;
 foreach($as as $a) {
  if($a->plaintext != "分店"){
   $a->href = "http://www.xx.com".$a->href;
   echo $a->outertext."------".$a->href."-------<br>";
   $sum++;
  }
 }
 echo "<br><br>第 {$i} 页结束 ,数目:{$sum}<hr>";
}
?>

在php中输出生成xml文件的方法有很多,有直接用header输入,也有使用DomDocument与SimpleXML实现创建xml文档的。

方法一

 代码如下 复制代码

function xml_out($content, $charset = 'utf-8') {
 @header("Expires: -1");
 @header("Cache-Control: no-store, private, post-check=0, pre-check=0, max-age=0", FALSE);
 @header("Pragma: no-cache");
 @header("Content-type: application/xml; charset=$charset");
 echo '<' . "?xml version="1.0" encoding="$charset"?>n";
 echo "<root><![CDATA[" . trim($content) . "]]></root>";
 exit();
}

方法二

 代码如下 复制代码

<?php
header("Content-type: text/xml");
echo "<?xml version="1.0" encoding="UTF-8"?>";
echo "<users><user><name>小小菜鸟</name><age>24</age><sex>男</sex></user><user><name>艳艳</name><age>23</age><sex>女</sex></user></users>";
?>

方法三


使用DomDocument生成XML文件

创建节点使用createElement方法,
创建文本内容使用createTextNode方法,
添加子节点使用appendChild方法,
创建属性使用createAttribute方法

 

 代码如下 复制代码
<?PHP
$data_array = array(
    array(
    'title' => 'title1',
    'content' => 'content1',
        'pubdate' => '2009-10-11',
    ),
    array(
    'title' => 'title2',
    'content' => 'content2',
    'pubdate' => '2009-11-11',
    )
);
 
//  属性数组
$attribute_array = array(
    'title' => array(
    'size' => 1
    )
);
 
//  创建一个XML文档并设置XML版本和编码。。
$dom=new DomDocument('1.0', 'utf-8');
 
//  创建根节点
$article = $dom->createElement('article');
$dom->appendchild($article);
 
foreach ($data_array as $data) {
    $item = $dom->createElement('item');
    $article->appendchild($item);
 
    create_item($dom, $item, $data, $attribute_array);
}
 
echo $dom->saveXML();
 
function create_item($dom, $item, $data, $attribute) {
    if (is_array($data)) {
        foreach ($data as $key => $val) {
            //  创建元素
            $$key = $dom->createElement($key);
            $item->appendchild($$key);
 
            //  创建元素值
            $text = $dom->createTextNode($val);
            $$key->appendchild($text);
 
            if (isset($attribute[$key])) {  //  如果此字段存在相关属性需要设置
                foreach ($attribute[$key] as $akey => $row) {
                    //  创建属性节点
                    $$akey = $dom->createAttribute($akey);
                    $$key->appendchild($$akey);
 
                    // 创建属性值节点
                    $aval = $dom->createTextNode($row);
                    $$akey->appendChild($aval);
                }
            }   //  end if
        }
    }   //  end if
}   //  end function
?>

方法四

SimpleXML输入xml格式编码

SimpleXML作为PHP核心的组成部分,可以把XML转换为对象,但是有时候,我需要对输出的xml格式设置编码;
代码:

 代码如下 复制代码

$XML = new SimpleXMLElement("<foo />"); echo($XML->asXML());

输出结果:

 代码如下 复制代码

<?xml version="1.0"?> <foo/>

如果想输出:

 代码如下 复制代码

<?xml version="1.0" encoding="UTF-8"?> <foo/>

在php中操作xml文档我们可以直接调用DOMDocument类或使用simplexml_load_string类来操作,这些都不需要加载算是内置函数了,我们直接使用。

是PHP脚本读取XML最原始,最笨的方法。

 代码如下 复制代码

$doc = new DOMDocument();
  
$doc->load('test.xml');
  
$rows = $doc->getElementsByTagName("ds");
  
$d = array();
  
$i = 0;
foreach($rows as $row)
{
   $web     = $row->getElementsByTagName('web');
   $webUrl  = $row->getElementsByTagName('webUrl');
   $d[$i]['web']    = $web->item(0)->nodeValue;
   $d[$i]['webUrl'] = $webUrl->item(0)->nodeValue;
   $i++;
}
  
print_R($d);


简单,容易,速度快

 代码如下 复制代码


$xmlData = file_get_contents('test.xml');
  
$xml = simplexml_load_string($xmlData);
  
$xmlArr = objectToArray($xml);

objectToArray函数代码如下

function objectToArray($object)
{  
   if(!$object) return '';
   $result = array();  
   $object = is_object($object) ? get_object_vars($object) : $object;  
   foreach ($object as $key => $val) {  
       $val = (is_object($val) || is_array($val)) ? objectToArray($val) : $val;  
       $result[$key] = $val;  
   }  
   return $result;  
}

上面讲到了读取xml,下面再介绍写xml实例

 代码如下 复制代码

$arr = array(
         array('id'=>1,'web'=>'好脚本','webUrl'=>'http://www.111cn.net'),
         array('id'=>2,'web'=>'PHP脚本','webUrl'=>'http://www.111cn.net/'),
         array('id'=>3,'web'=>'JavaScript脚本','webUrl'=>'http://www.111cn.net/'),
         array('id'=>4,'web'=>'js脚本','webUrl'=>'http://www.111cn.net/'),
         array('id'=>5,'web'=>'PHP脚本示例','webUrl'=>'http://www.111cn.net/'),
         array('id'=>5,'web'=>'JavaScript脚本示例','webUrl'=>'http://www.111cn.net/')
         );
/*使用dom生成xml,注意生成的xml中会没有空格。*/
$dom=new DOMDocument('1.0','utf-8');
  
$path= "logs/test.xml";
  
$data=$dom->createElement('data');
  
$dom->appendChild($data);
  
foreach($arr as $v)
{
    $ds = $dom->createElement('ds');
  
    $id = $dom->createAttribute('id'); 
      
    $id->nodeValue = $v['id'];
   
    $ds->setAttributeNode($id);
  
    $data->appendChild($ds);
  
    foreach($v as $kk=>$vv)
    {
       ${$kk} = $dom->createElement($kk); 
              
       $value= $dom->createTextNode($vv);
      
       ${$kk}->appendChild($value);
  
       $ds->appendChild(${$kk});
  
    }
}
  
$dom->saveXML();
  
$dom->save($path);

本文章来给大家介绍一个PHP 操作xml编程之xml的crud操作,有需要了解的同学可参考。

html代码页面

 代码如下 复制代码

<html>
<head>
    <meta http-equiv="Content-type" content="text/html;charset=utf-8">
</head>
<body>
    <form action="wordProcess.php" method="post">
        <input type="text" name="enword">
        <input type="hidden" name="type" value="query">
        <input type="submit" value="查询">
    </form>
    <span>添加单词</span>
    <form action="wordProcess.php" method="post">
        英文:<input type="text" name="enword"><br>
        中文:<input type="text" name="zhword"><br>
        <!--<input type="hidden" name="type" value="insert">
        <input type="hidden" name="type" value="update"> -->
        <input type="submit" name="type" value="添加">
        <input type="submit" name="type" value="修改">
    </form>
    <form action="wordProcess.php" method="post">
        <input type="text" name="word">
        <input type="hidden" name="type" value="delete">
        <input type="submit" value="删除">
    </form>
</body>
</html>

wordpress.php文件

 代码如下 复制代码


<?php

    //接收类型 看看用户做什么(查询、添加....)
    $type=$_REQUEST['type'];
    //echo $type;
    //exit();
    //创建xml文档对象
    $doc=new DOMDocument();
    $doc->load("words.xml");

    //进行判断
    if($type=="query"){
        //获取用户输入的值
        $enword=$_REQUEST['enword'];
       
        //判断是否进入查询
        $isEnter=false;
        //获取所有单词节点
        $words=$doc->getElementsByTagName("word");
        //遍历单词节点
        for($i=0;$i<$words->length;$i++){
            $word_node=$words->item($i);
            //获取不同的语种
            $en_word=getNodeVal($word_node,"en");
            $zh_word=getNodeVal($word_node,"zh");
            //查询
            if($enword==$en_word){
                $isEnter=true;
                echo $enword."的中文意思是:".getNodeVal($word_node,"zh");
                echo "<br/><a href='wordView.php'>返回继续查询</a>";
            }else if($enword==$zh_word){
                $isEnter=true;
                echo $enword."的英文意思是:".getNodeVal($word_node,"en");
                echo "<br/><a href='wordView.php'>返回继续查询</a>";
            }
        }

        if(!$isEnter){
            echo "无法查询";
            echo "<br/><a href='wordView.php'>返回继续查询</a>";
        }
    }else if($type=="添加"){
        //接收
        $enword=$_REQUEST['enword'];
        $zhword=$_REQUEST['zhword'];
        if(!empty($enword)&&!empty($zhword)){   
            //获取根节点
            $root=$doc->getElementsByTagName("words")->item(0);
           
            $word=$doc->createElement("word");
            $en=$doc->createElement("en",$enword);
            $zh=$doc->createElement("zh",$zhword);

            //进行挂载

            $root->appendChild($word);
            $word->appendChild($en);
            $word->appendChild($zh);

            //保存xml文件
            $doc->save("words.xml");
            echo "添加成功<br/><a href='wordView.php'>返回继续操作</a>";
        }else{
           
            echo "请输入单词";
            echo "<br/><a href='wordView.php'>返回继续操作</a>";
            exit();
        }
    }else if($type=="delete"){
       
        $word=$_REQUEST['word'];
        //获取所有单词节点
        $words=$doc->getElementsByTagName("word");
        $isEnter=false;
        //遍历单词节点
        for($i=0;$i<$words->length;$i++){
            $word_node=$words->item($i);
            //获取不同的语种
            $en_word=getNodeVal($word_node,"en");
            $zh_word=getNodeVal($word_node,"zh");
            //查询
            if($word==$en_word || $word==$zh_word){
                $isEnter=true;
                //找到父节点
                $word_node->parentNode->removeChild($word_node);
                $doc->save("words.xml");
                echo "删除成功<br/><a href='wordView.php'>返回继续操作</a>";
            }
        }

        if(!$isEnter){
            echo "操作失败";
            echo "<br/><a href='wordView.php'>返回继续操作</a>";
        }
    }else if($type="修改"){
        //接收
        $enword=$_REQUEST['enword'];
        $zhword=$_REQUEST['zhword'];
        if(!empty($enword)&&!empty($zhword)){   
            //获取所有单词节点
            $words=$doc->getElementsByTagName("word");
            //遍历单词节点
            $isEnter=false;
            for($i=0;$i<$words->length;$i++){
                $word_node=$words->item($i);
                //获取不同的语种
                $en_word=getNodeVal($word_node,"en");
                $zh_word=getNodeVal($word_node,"zh");
                //查询
                if($enword==$en_word && $zhword!=$zh_word){
                    //修改中文
                    $isEnter=true;
                    //获取zh节点
                    $zh=$word_node->getElementsByTagName("zh")->item(0);
                    $zh->nodeValue=$zhword;
                    $doc->save("words.xml");
                    echo "修改成功";
                    echo "<br/><a href='wordView.php'>返回继续操作</a>";
                }else if($enword!=$en_word && $zhword==$zh_word){
                    //修改因为
                    $isEnter=true;
                    $en=$word_node->getElementsByTagName("en")->item(0);
                    $en->nodeValue=$enword;
                    $doc->save("words.xml");
                    echo "修改成功";
                    echo "<br/><a href='wordView.php'>返回继续操作</a>";
                }   
            }

            if(!$isEnter){
                echo "没有做任何修改";
                echo "<br/><a href='wordView.php'>返回继续操作</a>";
            }

        }else{
            echo "请输入需要修改的单词";
            echo "<br/><a href='wordView.php'>返回继续操作</a>";
            exit();
        }
    }
   
    //获取节点的文本值
    function getNodeVal(&$MyNode,$tagName){
        return $MyNode->getElementsByTagName($tagName)->item(0)->nodeValue;
    }
?>

words.xml

 代码如下 复制代码

<?xml version="1.0" encoding="utf-8"?>
<words><word><en>boy</en><zh>男孩</zh></word><word><en>girl</en><zh>女孩</zh></word><word><en>fire</en><zh>火</zh></word><word><en>word</en><zh>词库</zh></word></words>

xml文件是一种数据存储格式,下面小编给大家介绍php解析xml格式文件的多种方法总结介绍,DOMDocument是我们常用的解析xml一个不错的方法,下面我来给大家总结总结。

DOMElement

DOMElement DOMDocument::createElement ( string $name [, string $value ] )

创建节点元素
String $name:节点名
String $value:节点的值
8、 添加节点
•DOMNode DOMNode::appendChild ( DOMNode $newnode )
添加子节点
   DOMNode $newnode:新节点
在dom操作中,增删改操作必须依赖于父节点
9、 保存
•string DOMDocument::saveXML
保存至某个字符串中
•int DOMDocument::save ( string $filename )
保存至某个文件中
String $filename:文件名
10、 删除节点
•DOMNode DOMNode::removeChild ( DOMNode $oldnode )
删除节点
DOMNode $oldnode:要删除的节点
11、 更新节点

•DOMNode DOMNode::replaceChild ( DOMNode $newnode , DOMNode $oldnode )
DOMNode $newnode:新节点
DOMNode $oldnode:原节点

12、 添加属性
•DOMAttr DOMElement::setAttribute( string $name , string $value )
string $name :属性名
string $value :属性值
13、 修改属性
      DOMAttr DOMElement::setAttribute( string $name , string $value )
string $name :属性名
string $value :属性值
14、 删除属性
•bool DOMElement::removeAttribute ( string $name )
string $name:要删除的属性名称
15、 获取属性
•string DOMElement::getAttribute ( string $name )
string $name:要获取的属性值的属性名

DOMDocument还是PHP5后推出的DOM扩展的一部分,可用来建立或解析html/xml,目前只支持utf-8编码。

 代码如下 复制代码

$xmlstring = <<<XML
<?xml version='1.0'?>
<document>
  <cmd attr='default'>login</cmd>
  <login>imdonkey</login>
</document>
XML;

$dom = new DOMDocument();
$dom->loadXML($xmlstring);
print_r(getArray($dom->documentElement));

function getArray($node) {
  $array = false;

  if ($node->hasAttributes()) {
    foreach ($node->attributes as $attr) {
      $array[$attr->nodeName] = $attr->nodeValue;
    }
  }

  if ($node->hasChildNodes()) {
    if ($node->childNodes->length == 1) {
      $array[$node->firstChild->nodeName] = getArray($node->firstChild);
    } else {
      foreach ($node->childNodes as $childNode) {
      if ($childNode->nodeType != XML_TEXT_NODE) {
        $array[$childNode->nodeName][] = getArray($childNode);
      }
    }
  }
  } else {
    return $node->nodeValue;
  }
  return $array;
}

 SimpleXML

SimpleXML是PHP5后提供的一套简单易用的xml工具集,可以把xml转换成方便处理的对象,也可以组织生成xml数据。不过它不适用于包含namespace的xml,而且要保证xml格式完整(well-formed)。它提供了三个方法:simplexml_import_dom、simplexml_load_file、simplexml_load_string,函数名很直观地说明了函数的作用。三个函数都返回SimpleXMLElement对象,数据的读取/添加都是通过SimpleXMLElement操作

 代码如下 复制代码


$string = <<<XML
<?xml version='1.0'?>
<document>
  <cmd>login</cmd>
  <login>imdonkey</login>
</document>
XML;

$xml = simplexml_load_string($string);
print_r($xml);
$login = $xml->login;//这里返回的依然是个SimpleXMLElement对象
print_r($login);
$login = (string) $xml->login;//在做数据比较时,注意要先强制转换
print_r($login);

SimpleXML的优点是开发简单,缺点是它会将整个xml载入内存后再进行处理,所以在解析超多内容的xml文档时可能会力不从心。如果是读取小文件,而且xml中也不包含namespace,那SimpleXML是很好的选择。


XMLReader

XMLReader也是PHP5之后的扩展(5.1后默认安装),它就像游标一样在文档流中移动,并在每个节点处停下来,操作起来很灵活。它提供了对输入的快速和非缓存的流式访问,可以读取流或文档,使用户从中提取数据,并跳过对应用程序没有意义的记录。
以一个利用google天气api获取信息的例子展示下XMLReader的使用,这里也只涉及到一小部分函数,更多还请参考官方文档。

 代码如下 复制代码

$xml_uri = 'http://www.google.com/ig/api?weather=Beijing&hl=zh-cn';
$current = array();
$forecast = array();

$reader = new XMLReader();
$reader->open($xml_uri, 'gbk');
while ($reader->read()) {
  //get current data
  if ($reader->name == "current_conditions" && $reader->nodeType == XMLReader::ELEMENT) {
    while($reader->read() && $reader->name != "current_conditions") {
      $name = $reader->name;
      $value = $reader->getAttribute('data');
      $current[$name] = $value;
    }
  }

  //get forecast data
  if ($reader->name == "forecast_conditions" && $reader->nodeType == XMLReader::ELEMENT) {
    $sub_forecast = array();
    while($reader->read() && $reader->name != "forecast_conditions") {
      $name = $reader->name;
      $value = $reader->getAttribute('data');
      $sub_forecast[$name] = $value;
    }
    $forecast[] = $sub_forecast;
  }
}
$reader->close();

XMLReader和XML Parser类似,都是边读边操作,较大的差异在于SAX模型是一个“推送”模型,其中分析器将事件推到应用程序,在每次读取新节点时通知应用程序,而使用XmlReader的应用程序可以随意从读取器提取节点,可控性更好。
由于XMLReader基于libxml,所以有些函数要参考文档看看是否适用于你的libxml版本。

[!--infotagslink--]

相关文章

  • php中网页添加到桌面快捷方式方法

    我们经常会在网站中看到可以直接把网站以快捷方式保存到自己的电脑中,然后只要点击就可以实现进入网了,那么php中怎么把网页添加到桌面快捷方式呢。 功能简单,直接上...2016-11-25
  • Windows批量搜索并复制/剪切文件的批处理程序实例

    这篇文章主要介绍了Windows批量搜索并复制/剪切文件的批处理程序实例,需要的朋友可以参考下...2020-06-30
  • PHP用DOM方式处理HTML之《Simple HTML DOM》

    近经常需要采集一些网上的数据,发现一个PHP处理HTML的利器 simple html dom,看了一下文档,使用非常方便,关键是能够用CSS选择器来访问DOM树,和jquery相似,实在是难得的利器...2016-11-25
  • BAT批处理判断服务是否正常运行的方法(批处理命令综合应用)

    批处理就是对某对象进行批量的处理,通常被认为是一种简化的脚本语言,它应用于DOS和Windows系统中。这篇文章主要介绍了BAT批处理判断服务是否正常运行(批处理命令综合应用),需要的朋友可以参考下...2020-06-30
  • PHP file_get_contents设置超时处理方法

    file_get_contents的超时处理话说,从PHP5开始,file_get_content已经支持context了(手册上写着:5.0.0 Added the context support. ),也就是说,从5.0开始,file_get_contents其实也可以POST数据。今天说的这篇是讲超时的,确实在...2013-10-04
  • C#多线程中的异常处理操作示例

    这篇文章主要介绍了C#多线程中的异常处理操作,涉及C#多线程及异常的捕获、处理等相关操作技巧,需要的朋友可以参考下...2020-06-25
  • ps中怎么设置垂直罗马对齐方式?垂直罗马对齐方式设置方法

    photoshop的直排文字工具,打出的字特别是英文字母,默认排列侧向的,如何调整为正向排列呢?下面我们就来看看标准的罗马对齐方式应该怎么设置。 1、在PS中点击“工具面...2017-01-22
  • postgresql 中的时间处理小技巧(推荐)

    这篇文章主要介绍了postgresql 中的时间处理小技巧(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-29
  • Python同时处理多个异常的方法

    这篇文章主要介绍了Python同时处理多个异常的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-29
  • C#异常处理中try和catch语句及finally语句的用法示例

    这篇文章主要介绍了C#异常处理中try和catch语句及finally语句的用法示例,finally语句的使用涉及到了C#的垃圾回收特性,需要的朋友可以参考下...2020-06-25
  • python用moviepy对视频进行简单的处理

    这篇文章主要介绍了python如何用moviepy对视频进行简单的处理,帮助大家更好的利用python处理视频,感兴趣的朋友可以了解下...2021-03-11
  • C#异常处理详解

    这篇文章介绍了C#异常处理,有需要的朋友可以参考一下...2020-06-25
  • sql server日志处理不当造成的隐患详解

    这篇文章主要给大家介绍了关于sql server日志处理不当造成的隐患的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用sql server具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-07-11
  • go语言中的Carbon库时间处理技巧

    这篇文章主要介绍了go语言中的Carbon库时间处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-05
  • Spring MVC 处理一个请求的流程

    Spring MVC是Spring系列框架中使用频率最高的部分。不管是Spring Boot还是传统的Spring项目,只要是Web项目都会使用到Spring MVC部分。因此程序员一定要熟练掌握MVC部分。本篇博客简要分析Spring MVC处理一个请求的流程。...2021-02-06
  • javascript 判断页面访问方式电脑或者移动端

    这篇文章主要介绍了 判断页面访问方式电脑或者移动端的相关资料,这里提供了三种方法,需要的朋友可以参考下...2016-10-03
  • C++异常处理入门(try和catch)

    C++ 提供了异常机制,让我们能够捕获运行时错误,本文就详细的介绍了C++异常处理入门,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-09
  • C#事务处理(Execute Transaction)实例解析

    这篇文章主要介绍了C#事务处理(Execute Transaction)实例解析,对于理解和学习事务处理有一定的帮助,需要的朋友可以参考下...2020-06-25
  • php图像处理(缩放、剪裁、缩放、翻转、旋转、透明、锐化)

    本文章来给各同学总结了一些常用的图像处理函数,包括有缩放、剪裁、缩放、翻转、旋转、透明、锐化功能,大家可参考参考。 注意事项:如果要使用php gd处理我们需要...2016-11-25
  • Python编程OpenCV和Numpy图像处理库实现图片去水印

    这篇文章主要介绍了Python编程中如何实现图片去水印本文采用了OpenCV和Numpy的图像处理的方法来实现,文中附含详细示例代码,有需要的朋友可以借鉴参考下...2021-09-26