整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          PHP中使用DOMDocument來(lái)處理HTML、XML文檔

          實(shí)從PHP5開(kāi)始,PHP就為我們提供了一個(gè)強(qiáng)大的解析和生成XML相關(guān)操作的類,也就是我們今天要講的 DOMDocument 類。不過(guò)我估計(jì)大部分人在爬取網(wǎng)頁(yè)時(shí)還是會(huì)喜歡用正則去解析網(wǎng)頁(yè)內(nèi)容,學(xué)了今天的這個(gè)類下回就可以嘗試下使用這個(gè)PHP自帶的方式來(lái)進(jìn)行解析分析了。

          解析HTML

          // 解析 HTML
          $baidu = file_get_contents('https://www.baidu.com');
          
          $doc = new DOMDocument();
          @$doc->loadHTML($baidu);
          
          // 百度輸出框
          $inputSearch = $doc->getElementById('kw');
          var_dump($inputSearch);
          
          // object(DOMElement)#2 
          //     ....
          
          echo $inputSearch->getAttribute('name'), PHP_EOL; // wd
          
          // 獲取所有圖片的鏈接
          $allImageLinks = [];
          $imgs = $doc->getElementsByTagName('img');
          foreach($imgs as $img){
              $allImageLinks[] = $img->getAttribute('src');
          }
          
          print_r($allImageLinks);
          
          // Array
          // (
          //     [0] => //www.baidu.com/img/baidu_jgylogo3.gif
          //     [1] => //www.baidu.com/img/bd_logo.png
          //     [2] => http://s1.bdstatic.com/r/www/cache/static/global/img/gs_237f015b.gif
          // )
          
          // 利用 parse_url 分析鏈接
          foreach($allImageLinks as $link){
              print_r(parse_url($link));
          }
          
          // Array
          // (
          //     [host] => www.baidu.com
          //     [path] => /img/baidu_jgylogo3.gif
          // )
          // Array
          // (
          //     [host] => www.baidu.com
          //     [path] => /img/bd_logo.png
          // )
          // Array
          // (
          //     [scheme] => http
          //     [host] => s1.bdstatic.com
          //     [path] => /r/www/cache/static/global/img/gs_237f015b.gif
          // )
          

          是不是感覺(jué)好清晰,好有面向?qū)ο蟮母杏X(jué)。就像第一次使用 ORM庫(kù) 來(lái)進(jìn)行數(shù)據(jù)庫(kù)操作一樣的感覺(jué)。我們一段一段來(lái)看。

          $baidu = file_get_contents('https://www.baidu.com');
          
          $doc = new DOMDocument();
          @$doc->loadHTML($baidu);
          

          首先是加載文檔內(nèi)容,這個(gè)比較好理解,直接使用 loadHTML() 方法加載 HTML 內(nèi)容。它還提供了其它的幾個(gè)方法,分別是:load() 從一個(gè)文件加載XML;loadXML() 從字符串加載XML;loadHTMLFile() 從文件加載HTML。

          // 百度輸出框
          $inputSearch = $doc->getElementById('kw');
          var_dump($inputSearch);
          
          // object(DOMElement)#2 
          //     ....
          
          echo $inputSearch->getAttribute('name'), PHP_EOL; // wd
          

          接下來(lái)我們使用和前端 JS 一樣的 DOM 操作API來(lái)操作HTML里面的元素。這個(gè)例子中就是獲取百度的文本框,直接使用 getElementById() 方法獲得id為指定內(nèi)容的 DOMElement 對(duì)象。然后就可以獲取它的值、屬性之類的內(nèi)容了。

          // 獲取所有圖片的鏈接
          $allImageLinks = [];
          $imgs = $doc->getElementsByTagName('img');
          foreach($imgs as $img){
              $allImageLinks[] = $img->getAttribute('src');
          }
          
          print_r($allImageLinks);
          
          // Array
          // (
          //     [0] => //www.baidu.com/img/baidu_jgylogo3.gif
          //     [1] => //www.baidu.com/img/bd_logo.png
          //     [2] => http://s1.bdstatic.com/r/www/cache/static/global/img/gs_237f015b.gif
          // )
          
          // 利用 parse_url 分析鏈接
          foreach($allImageLinks as $link){
              print_r(parse_url($link));
          }
          
          // Array
          // (
          //     [host] => www.baidu.com
          //     [path] => /img/baidu_jgylogo3.gif
          // )
          // Array
          // (
          //     [host] => www.baidu.com
          //     [path] => /img/bd_logo.png
          // )
          // Array
          // (
          //     [scheme] => http
          //     [host] => s1.bdstatic.com
          //     [path] => /r/www/cache/static/global/img/gs_237f015b.gif
          // )
          

          這一段例子則是獲取HTML文檔中所有的圖片鏈接。相比正則來(lái)說(shuō),是不是方便很多,而且代碼本身就是自解釋的,不用考慮正則的匹配失效的問(wèn)題。配合另外一個(gè)PHP中自帶的 parse_url() 方法也能非常方便地對(duì)鏈接進(jìn)行分析,提取自己想要的內(nèi)容。

          XML的解析和對(duì)HTML的解析也是類似的,都使用 DOMDocument 和 DOMElement 提供的這個(gè)方法接口就可以很方便的進(jìn)行解析了。那么我們想要生成一個(gè)標(biāo)準(zhǔn)格式的XML呢?當(dāng)然也非常的簡(jiǎn)單,不需要再去拼接字符串了,使用這個(gè)類一樣的進(jìn)行對(duì)象化的操作。

          生成一個(gè)XML

          // 生成一個(gè)XML文檔
          $xml = new DOMDocument('1.0', 'UTF-8');
          
          $node1 = $xml->createElement('First', 'This is First Node.');
          $node1->setAttribute('type', '1');
          
          $node2 = $xml->createElement('Second');
          $node2->setAttribute('type', '2');
          $node2_child = $xml->createElement('Second-Child', 'This is Second Node Child.');
          $node2->appendChild($node2_child);
          
          $xml->appendChild($node1);
          $xml->appendChild($node2);
          print $xml->saveXML();
          
          /*
          <?xml version="1.0" encoding="UTF-8"?>
          <First type="1">This is First Node.</First>
          <Second type="2"><Second-Child>This is Second Node Child.</Second-Child></Second>
          */
          

          其實(shí)只要有一點(diǎn)點(diǎn)的前端 JS 的基礎(chǔ)都不難看出這段代碼的含義。使用 createElement() 方法創(chuàng)造 DOMElement 對(duì)象,然后就可以為它添加屬性和內(nèi)容。使用 appendChild() 方法就可以為當(dāng)前的 DOMElement 或者 DOMDocument 添加下級(jí)節(jié)點(diǎn)。最后使用 saveXML() 就能夠生成標(biāo)準(zhǔn)的XML格式內(nèi)容了。

          總結(jié)

          通過(guò)上面兩個(gè)簡(jiǎn)單的小例子,相信大家已經(jīng)對(duì)這個(gè) DOMDocument 操作XML類文件解析的方式非常感興趣了。不過(guò)相對(duì)于正則解析的方式它們的性能有多大的差異并沒(méi)有找到相關(guān)的測(cè)試,不過(guò)一般正常的情況下網(wǎng)站的HMTL文檔都不會(huì)太大,畢竟各個(gè)網(wǎng)站也會(huì)考慮自身的加載速度,如果文檔非常大的話用戶體驗(yàn)也會(huì)很差,所以這套接口用來(lái)進(jìn)行日常爬蟲(chóng)的分析處理工作基本是沒(méi)有任何問(wèn)題的。

          測(cè)試代碼: https://github.com/zhangyue0503/dev-blog/blob/master/php/202002/source/PHP%E4%B8%AD%E4%BD%BF%E7%94%A8DOMDocument%E6%9D%A5%E5%A4%84%E7%90%86HTML%E3%80%81XML%E6%96%87%E6%A1%A3.php

          參考文檔: https://www.php.net/manual/zh/class.domdocument.php

          HTML DOM 允許 JavaScript 改變 HTML 元素的樣式。

          改變 HTML 樣式

          如需改變 HTML 元素的樣式,請(qǐng)使用這個(gè)語(yǔ)法:

          document.getElementById(id).style.property=新樣式

          下面的例子會(huì)改變 <p> 元素的樣式:

          實(shí)例

          <html>

          <body>

          <p id="p2">Hello World!</p>

          <script>

          document.getElementById("p2").style.color="blue";

          </script>

          <p>以上段落通過(guò)腳本修改。</p>

          </body>

          </html>

          使用事件

          HTML DOM 允許我們通過(guò)觸發(fā)事件來(lái)執(zhí)行代碼。

          比如以下事件:

          • 元素被點(diǎn)擊。

          • 頁(yè)面加載完成。

          • 輸入框被修改。

          • ……

          在接下來(lái)我介紹關(guān)于事件的知識(shí)。

          本例改變了 id="id1" 的 HTML 元素的樣式,當(dāng)用戶點(diǎn)擊按鈕時(shí):

          實(shí)例

          <!DOCTYPE html>

          <html>

          <body>

          <h1 id="id1">我的標(biāo)題 1</h1>

          <button type="button"

          onclick="document.getElementById('id1').style.color='red'">

          點(diǎn)我!</button>

          </body>

          </html>

          如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!

          檔對(duì)象模型(Document Object Model,DOM)是一種抽象化表示網(wǎng)頁(yè)的方法,文檔是以樹(shù)形結(jié)構(gòu)表示的。

          Document節(jié)點(diǎn)分為父節(jié)點(diǎn)(parentNode)、子節(jié)點(diǎn)(childNode)、兄弟節(jié)點(diǎn)(siblingNode)等。

          BOM(瀏覽器對(duì)象模型)因?yàn)闆](méi)有一個(gè)標(biāo)準(zhǔn)來(lái)定義瀏覽器的功能,所以不同的瀏覽器有不同的屬性和方法。DOM則不然,有專門定義HTML(或XML)頁(yè)面中的對(duì)象應(yīng)該如何表示的標(biāo)準(zhǔn)。開(kāi)發(fā)人員可以使用DOM操作或查找網(wǎng)頁(yè)中的某項(xiàng)內(nèi)容,尤其是表單、圖片、定位元素。

          1 查詢或訪問(wèn)的方法

          當(dāng)HTML文檔加載完成后,瀏覽器將會(huì)將其表示成樹(shù)形結(jié)構(gòu),頁(yè)面上的所有元素都是對(duì)象樹(shù)中的對(duì)象。如JS在處理表單時(shí),會(huì)根據(jù)其在文檔中出現(xiàn)的次序?yàn)樗斜韱蝿?chuàng)建一個(gè)數(shù)組。document.forms[0]用來(lái)表示第一個(gè)表單。同樣,頁(yè)面上所有的圖片、鏈接和錨點(diǎn)都會(huì)以其名字存儲(chǔ)在數(shù)組中,例如document.images、document.links、document.anchors[]等。

          1.1 數(shù)組通過(guò)名字或索引

          如文檔中有一個(gè)表單,名字是form1,那么就可以通過(guò)它的名字來(lái)訪問(wèn)它,即document.forms["form1"],也可以使用索引值來(lái)訪問(wèn)它,即document.forms[n].

          1.2 通過(guò)document方法的name屬性

          document.getElementByTagName();

          1.3 通過(guò)document方法的ID屬性

          document.getElementById();

          2 DOM的修改

          window.onload=function(){

          var divObj = document.getElementById("divtest");

          divObj.innerHTML = "Inserting new text in the div container!";

          }

          3 DOM的追加

          window.onload=function(){

          var para = document.createElement("p");

          var divObj = document.getElementById("divtest");

          divObj.appendChild(para);

          var txt = document.createTextNode("Hope this work!");

          para.appendChild(txt);

          }

          4 DOM節(jié)點(diǎn)的插入

          document.body.insertbefore(newPara, firstPara);

          5 為DOM節(jié)點(diǎn)創(chuàng)建屬性

          var headings = document.getElementsByTagName("h4");

          headings[0].setAttribute("id", "firsth4");

          6 DOM的復(fù)制

          newPara = oldPara.cloneNode(true);

          7 DOM的刪除

          parentDiv1.removeChild(div2);

          補(bǔ)充:

          document.write()方法

          可以寫入全部的文檔代碼,包括HTML、CSS乃至JS。

          -End-


          主站蜘蛛池模板: 国产精品一区三区| 国产一区二区视频免费| 亚洲AV成人一区二区三区观看| 波多野结衣一区二区三区高清av| 国产a∨精品一区二区三区不卡| 无码日韩人妻AV一区二区三区| 精品无码一区二区三区爱欲九九| 精品亚洲一区二区三区在线观看| 韩国女主播一区二区| 中文乱码人妻系列一区二区| 亚洲AV无码一区二区乱子伦| 综合久久一区二区三区 | 成人久久精品一区二区三区| 亚洲av午夜福利精品一区| 亚洲熟女乱综合一区二区| 日韩熟女精品一区二区三区| 亚洲AV无码国产一区二区三区| 91无码人妻精品一区二区三区L| 国产av一区二区三区日韩| 久久久无码精品国产一区| 久久精品一区二区三区日韩| 午夜福利一区二区三区高清视频| 亚洲一区AV无码少妇电影☆| 波多野结衣免费一区视频| 国产一区二区三区高清在线观看| 国产AⅤ精品一区二区三区久久| 免费一区二区无码视频在线播放| 视频在线一区二区| 精品视频一区二区三区| 中文字幕在线无码一区| 久久高清一区二区三区| 中文字幕在线一区二区在线| 在线精品一区二区三区| 国产在线观看91精品一区| 免费人妻精品一区二区三区| 国产观看精品一区二区三区| 久久青草精品一区二区三区| 亚洲AV无码一区二区三区在线| 毛片一区二区三区| 成人在线一区二区| 日本一区二区三区精品中文字幕|