PHP類推薦:QueryList|基於phpQuery的無比強大的PHP採集工具
阿新 • • 發佈:2018-11-11
QueryList的出現讓PHP做採集從未如此簡單。得益於phpQuery,讓使用QueryList幾乎沒有任何學習成本,只要會CSS3選擇器就可以輕鬆使用QueryList了,和jQuery選擇器用法完全通用,它讓PHP做採集像jQuery選擇元素一樣簡單。
初探
看看PHP用QueryList做採集到底有多簡潔吧!
<?php use QL\QueryList; //採集某頁面所有的圖片 $data = QueryList::Query('http://cms.querylist.cc/bizhi/453.html',array( //採集規則庫 //'規則名' => array('jQuery選擇器','要採集的屬性'), 'image' => array('img','src') ))->data; //列印結果 print_r($data); //採集某頁面所有的超連結 //可以先手動獲取要採集的頁面原始碼 $html = file_get_contents('http://cms.querylist.cc/google/list_1.html'); //然後可以把頁面原始碼或者HTML片段傳給QueryList $data = QueryList::Query($html,array( 'link' => array('a','href') ))->data; //列印結果 print_r($data); /** * 線上測試採集並檢視採集結果:http://querylist.cc/page-Querytest.html */
進階
上面的採集結果有很多“雜質”,一定不會滿足你的要求,來獲取我們真正想要的結果。
<?php use QL\QueryList; //採集該頁面[正文內容]中所有的圖片 $data = QueryList::Query('http://cms.querylist.cc/bizhi/453.html',array( 'image' => array('.post_content img','src') ))->data; //列印結果 print_r($data); //採集該頁面文章列表中所有[文章]的超連結 $data = QueryList::Query('http://cms.querylist.cc/google/list_1.html',array( 'link' => array('h2>a','href','',function($content){ //利用回撥函式補全相對連結 $baseUrl = 'http://cms.querylist.cc'; return $baseUrl.$content; })),'.cate_list li')->data; //列印結果 print_r($data);
全貌
正如你看到的那樣,QueryList只有一個主要的方法Query,學會了使用Query方法也就意味著你已經熟練了QueryList!
<?php /** * 下面來完整的演示採集一篇文章頁的文章標題、釋出日期和文章內容 */ //引入自動載入檔案 require 'vendor/autoload.php'; /** * 或者手動引入 * * 引入QueryList依賴 * require 'QueryList/phpQuery.php'; * 引入QueryList * require 'QueryList/QueryList.php'; */ use QL\QueryList; //需要採集的目標頁面 $page = 'http://cms.querylist.cc/news/566.html'; //採集規則 $reg = array( //採集文章標題 'title' => array('h1','text'), //採集文章釋出日期,這裡用到了QueryList的過濾功能,過濾掉span標籤和a標籤 'date' => array('.pt_info','text','-span -a',function($content){ //用回撥函式進一步過濾出日期 $arr = explode(' ',$content); return $arr[0]; }), //採集文章正文內容,利用過濾功能去掉文章中的超連結,但保留超連結的文字,並去掉版權、JS程式碼等無用資訊 'content' => array('.post_content','html','a -.content_copyright -script',function($content){ //利用回撥函式下載文章中的圖片並替換圖片路徑為本地路徑 //使用本例請確保當前目錄下有image資料夾,並有寫入許可權 //由於QueryList是基於phpQuery的,所以可以隨時隨地使用phpQuery,當然在這裡也可以使用正則或者其它方式達到同樣的目的 $doc = phpQuery::newDocumentHTML($content); $imgs = pq($doc)->find('img'); foreach ($imgs as $img) { $src = 'http://cms.querylist.cc'.pq($img)->attr('src'); $localSrc = 'image/'.md5($src).'.jpg'; $stream = file_get_contents($src); file_put_contents($localSrc,$stream); pq($img)->attr('src',$localSrc); } return $doc->htmlOuter(); }) ); $rang = '.content'; $ql = QueryList::Query($page,$reg,$rang); $data = $ql->getData(); //列印結果 print_r($data);
擴充套件
QueryList的功能很單一,就是Query,但擴充套件讓QueryList變得無限可能!
<?php
/**
* 目前已經有:HTTP操作、多執行緒、模擬登陸等QueryList擴充套件
* 下面來利用QueryList擴充套件來組合上面的例子,實現多執行緒採集文章並儲存文章圖片到本地
*/
use QL\QueryList;
//HTTP操作擴充套件
$urls = QueryList::run('Request',[
'target' => 'http://cms.querylist.cc/news/list_2.html',
'referrer'=>'http://cms.querylist.cc',
'method' => 'GET',
'params' => ['var1' => 'testvalue', 'var2' => 'somevalue'],
'user_agent'=>'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0',
'cookiePath' => './cookie.txt',
'timeout' =>'30'
])->setQuery(['link' => ['h2>a','href','',function($content){
//利用回撥函式補全相對連結
$baseUrl = 'http://cms.querylist.cc';
return $baseUrl.$content;
}]],'.cate_list li')->getData(function($item){
return $item['link'];
});
//多執行緒擴充套件
QueryList::run('Multi',[
'list' => $urls,
'curl' => [
'opt' => array(
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_AUTOREFERER => true,
),
//設定執行緒數
'maxThread' => 100,
//設定最大嘗試數
'maxTry' => 3
],
'success' => function($a){
//採集規則
$reg = array(
//採集文章標題
'title' => array('h1','text'),
//採集文章釋出日期,這裡用到了QueryList的過濾功能,過濾掉span標籤和a標籤
'date' => array('.pt_info','text','-span -a',function($content){
//用回撥函式進一步過濾出日期
$arr = explode(' ',$content);
return $arr[0];
}),
//採集文章正文內容,利用過濾功能去掉文章中的超連結,但保留超連結的文字,並去掉版權、JS程式碼等無用資訊
'content' => array('.post_content','html','a -.content_copyright -script',function($content){
//利用回撥函式下載文章中的圖片並替換圖片路徑為本地路徑
//使用本例請確保當前目錄下有image資料夾,並有寫入許可權
//由於QueryList是基於phpQuery的,所以可以隨時隨地使用phpQuery,當然在這裡也可以使用正則或者其它方式達到同樣的目的
$doc = phpQuery::newDocumentHTML($content);
$imgs = pq($doc)->find('img');
foreach ($imgs as $img) {
$src = pq($img)->attr('src');
$localSrc = 'image/'.md5($src).'.jpg';
$stream = file_get_contents($src);
file_put_contents($localSrc,$stream);
pq($img)->attr('src',$localSrc);
}
return $doc->htmlOuter();
})
);
$rang = '.content';
$ql = QueryList::Query($a['content'],$reg,$rang);
$data = $ql->getData();
//列印結果,實際操作中這裡應該做入資料庫操作
print_r($data);
}
]);