>[info]場景:爬蟲爬完取數據
下載地址:https://github.com/samacs/simple_html_dom
[toc]
解析器不僅僅只是幫助我們驗證html文檔;
更能解析不符合W3C標準的html文檔。
它使用了類似jQuery的元素選擇器,通過元素的id,class,tag等等來查找定位;同時還提供添加、刪除、修改文檔樹的功能。當然,這樣一款強大的html Dom解析器也不是盡善盡美;在使用的過程中需要十分小心內存消耗的情況。不過,不要擔心;最后會為各位介紹如何避免消耗過多的內存。
## :-: **開始使用**
上傳類文件以后,有三種方式調用這個類:
從url中加載html文檔
從字符串中加載html文檔
從文件中加載html文檔
~~~
<?php
// 新建一個Dom實例
$html = new simple_html_dom();
// 從url中加載
$html->load_file('http://www.jb51.net');
// 從字符串中加載
$html->load('<html><body>從字符串中加載html文檔演示</body></html>');
//從文件中加載
$html->load_file('path/file/test.html');
?>
~~~
如果從字符串加載html文檔,需要先從網絡上下載。建議使用CURL來抓取html文檔并加載DOM中。
PHP Simple HTML DOM Parser提供了3種方式來創建DOM對象 :
~~~
// Create a DOM object from a string
$html = str_get_html('<html><body>Hello!</body></html>');
// Create a DOM object from a URL
$html = file_get_html('http://www.google.com/');
// Create a DOM object from a HTML file
$html = file_get_html('test.htm');
~~~
## :-: **查找html元素**
可以使用find函數來查找html文檔中的元素。返回的結果是一個包含了對象的數組。我們使用HTML DOM解析類中的函數來訪問這些對象,下面給出幾個示例
~~~
<?php
//查找html文檔中的超鏈接元素
$a = $html->find('a');
//查找文檔中第(N)個超鏈接,如果沒有找到則返回空數組.
$a = $html->find('a', 0);
// 查找id為main的div元素
$main = $html->find('div[id=main]',0);
// 查找所有包含有id屬性的div元素
$divs = $html->find('div[id]');
// 查找所有包含有id屬性的元素
$divs = $html->find('[id]');
?>
~~~
還可以使用類似jQuery的選擇器來查找定位元素:
~~~
<?php
// 查找id='#container'的元素
$ret = $html->find('#container');
// 找到所有class=foo的元素
$ret = $html->find('.foo');
// 查找多個html標簽
$ret = $html->find('a, img');
~~~
解析器支持對子元素的查找
~~~
<?php
// 查找 ul列表中所有的li項
$ret = $html->find('ul li');
//查找 ul 列表指定class=selected的li項
$ret = $html->find('ul li.selected');
?>
~~~
如果你覺得這樣用起來麻煩,使用內置函數可以輕松定位元素的父元素、子元素與相鄰元素
~~~
<?php
// 返回父元素
$e->parent;
// 返回子元素數組
$e->children;
// 通過索引號返回指定子元素
$e->children(0);
// 返回第一個資源速
$e->first_child ();
// 返回最后一個子元素
$e->last_child ();
// 返回上一個相鄰元素
$e->prev_sibling ();
//返回下一個相鄰元素
$e->next_sibling ();
?>
~~~
## :-: **元素屬性操作**
使用簡單的正則表達式來操作屬性選擇器。
[attribute] – 選擇包含某屬性的html元素
[attribute=value] – 選擇所有指定值屬性的html元素
[attribute!=value]- 選擇所有非指定值屬性的html元素
[attribute^=value] -選擇所有指定值開頭屬性的html元素
[attribute$=value] 選擇所有指定值結尾屬性的html元素
[attribute*=value] -選擇所有包含指定值屬性的html元素
在解析器中調用元素屬性
在DOM中元素屬性也是對象:
``` php
<?php
// 本例中將$a的錨鏈接值賦給$link變量
$link = $a->href;
?>
```
或者
```php
<?php
$link = $html->find('a',0)->href;
?
```
每個對象都有4個基本對象屬性:
tag – 返回html標簽名
innertext – 返回innerHTML
outertext – 返回outerHTML
plaintext – 返回html標簽中的文本
在解析器中編輯元素
編輯元素屬性的用法和調用它們是類似的:
~~~
<?php
//給$a的錨鏈接賦新值
$a->href = 'http://www.jb51.net';
// 刪除錨鏈接
$a->href = null;
// 檢測是否存在錨鏈接
if(isset($a->href)) {
//代碼
}
?>
~~~
解析器中沒有專門的方法來添加、刪除元素,不過可以變通一下使用:
~~~
<?php
// 封裝元素
$e->outertext = '<div class="wrap">' . $e->outertext . '<div>';
// 刪除元素
$e->outertext = '';
// 添加元素
$e->outertext = $e->outertext . '<div>foo<div>';
// 插入元素
$e->outertext = '<div>foo<div>' . $e->outertext;
?>
~~~
保存修改后的html DOM文檔也非常簡單:
``` php
<?php
$doc = $html;
// 輸出
echo $doc;
?>
```
## :-: **如何避免解析器消耗過多內存**
Simple HTML DOM解析器消耗內存過多的問題。
如果php腳本占用內存太多,會導致網站停止響應等一系列嚴重的問題。
解決的方法也很簡單,在解析器加載html文檔并使用完成后,記得清理掉這個對象就可以了。
當然,也不要把問題看得太嚴重了。如果只是加載了2、3個文檔,清理或不清理是沒有多大區別的。當你加載了5個10個甚至更多的文檔的時候,用完一個就清理一下內存
``` php
<?php
$html->clear();
?>
```
## :-: **示例**
### :-: **效果**

### :-: **php代碼**
~~~
<?php
header("Content-type: text/html; charset=utf-8");
include('simple_html_dom/simple_html_dom.php');//引入類庫文件
$html = file_get_html('dom.html');//獲取html文件
//給頁面中的a標簽添加類名、設置樣式
$html->find('a',0)->setAttribute('class','bar');
$html->find('a',0)->setAttribute('style','color:red');
//打印指定標簽內容
foreach($html->find('div#gbar') as $e) echo $e->innertext . '<br>';
//向指定標簽中添加內容
$aaa = [1,2,3];
$tr = '';
foreach($aaa as $color)
$tr.="<td>".$color."</td>";
$html->find('tr',3)->innertext = $tr;
//保存修改到指定文件
$html->save('demo.html');
?>
~~~
### :-: **html文件**
~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>php_simple_dom</title>
</head>
<body>
<div class="container" id="gbar">
<h1>一娃</h1>
<h2>二娃</h2>
<h3>三娃</h3>
<ul>
<li>吉林</li>
<li>遼寧</li>
<li>上海</li>
<li>廣州</li>
</ul>
<input type="text" value="111"/>
<input type="datetime"/>
<textarea>lallallallalala</textarea>
<a href="https://www.baidu.com" class="bar" color="red" style="color:red">百度一下</a>
<img src="https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2812136344,465892702&fm=58"
style="width: 30px;height: 30px">
<span class="gb1">這是span標簽</span>
<button>提交</button>
<br>
<table>
<thead>
<tr>
<th>1111</th>
<th>2222</th>
<th>3333</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">121212</td>
<td>343434</td>
<td>565656</td>
</tr>
<tr>
<td>121212</td>
<td>343434</td>
<td>565656</td>
</tr>
<tr></tr>
</tbody>
</table>
<div>hahahhaha</div>
</div>
</body>
</html>
~~~
- 雜談
- 開發 & 維護的工作流程
- 新手如何看php手冊 和 框架手冊
- 開發 & 維護的不同點
- 從0到1,搭建新項目的工作流程
- 從1到N,維護的工作流程
- 優化流程
- 生成錯誤日志和慢日志的方法
- 查錯思路
- 怎么快速接手一個項目
- 前端常用知識點
- javascript
- 自己封裝的函數
- 處理數字
- 功能代碼
- 動態添加圖片
- 判斷是手機端還是pc端
- javascript:;是什么意思?怎么用呢
- html & h5
- a標簽中target設置為blank和_blank有什么區別?
- 亂碼
- 提交方式:button標簽 和 input
- 塊元素
- 內聯元素
- h5特有屬性
- h5的localStorage【增、刪、改、查】
- jquery
- 常用方法
- 功能代碼
- 動態刪除圖片
- 一個按鈕,切換2種狀態
- 換膚
- 深入理解(function(){... })();
- json & xml
- json
- 語法速記
- json對象取值
- 字符串、對象、數組的區別
- xml
- [CDATA[%s]]的作用是什么
- 轉義字符
- CDATA 想被xml解析的文本數據
- CDATA 不想被xml解析的文本數據
- 微信小程序
- 其他
- websocket
- 跨域
- css
- 行內 & 內連 & 外連 寫法
- 優先級
- 更加精準的匹配
- 使用百分比如何生效
- php在html、js、jq中的的原生寫法
- *php在html中的語法
- php在js中的語法
- php在jq中的語法
- 正則表達式
- php常用基礎知識(思想為主)
- php為什么是“邊編譯邊運行”
- 冒號、endif、endwhile、endfor使用
- 遞歸思想(速記法)
- cookie和session的理解
- php常用內置(系統)函數
- 常量
- 字符串
- 數組
- 日期時間
- 文件 & 目錄
- 數學
- 程序執行
- 判斷
- 選項和信息(修改配置文件的)
- 錯誤處理 & 日志記錄
- 編碼格式
- session
- IP相關
- 類 & 對象
- 性能
- 其他函數
- 魔術方法
- $_SERVER
- 變量處理
- php自己封裝的一些函數
- 導入、導出、生成文件
- 數組
- 數字
- 字符串
- 其他
- 獲取linux硬件信息
- 常見插件/類庫使用
- 前端-框架/插件
- bootstrap 學習筆記
- layer 學習筆記
- layDate 學習筆記
- 百度ueditor1.4.4.3富文本編輯器
- quill富文本編輯器
- 百度ECharts圖形報表
- webuploader上傳圖片
- 后端類庫
- workerman 聊天室
- QRCODE 二維碼
- redis
- seaslog 日志
- phpspider 爬蟲
- Mailer 發送郵件
- simple_html_dom
- phpstorm使用
- 快捷鍵
- 連接mysql數據庫
- 斷點 + debug調試
- 運行內存不夠
- wamp環境
- yii、laravel、tp、開發自己的php框架
- 看框架源碼的思路
- tp5框架的使用
- 1、助手函數原理解析
- 開發自己的php框架
- 常用的開發思路 和 小功能實現代碼
- 爬蟲思路
- 功能點思路
- tp5判斷是不是異地登錄(簡單版)
- 微信開發,反向代理
- 微信開發,關閉當前頁面
- 消息隊列的實現
- 頁面靜態化
- session串號
- 站內信設計思路
- web在線管理器
- 語言相關(開發有關)
- 接收json(text/xml)格式數據
- 原生文件上傳(狀態碼)
- openssl擴展
- 打印對象 和 遍歷對象
- 使用OB緩存的幾個原則
- CLI模式執行php文件
- foreach時,添加元素 或 修改元素的值
- 功能點 代碼實現
- 生成url目錄樹(沒有pid)
- 多圖上傳(vue傳base64)
- 下載文件,耗時算法
- 生成商品二維碼
- 導出excel
- 搜索
- 阿里大魚發短信
- 使用阿里云oss
- location.href跳轉后,丟失用戶的session
- “\r ” “\r\n” “\t”的區別
- php的配置文件詳解
- 開啟錯誤日志
- 開啟慢日志
- 開啟短標簽
- 分析php-fpm.conf中的request_terminate_timeout參數