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);
}
]);
来源:51CTO
作者:gutaotao1989
链接:https://blog.51cto.com/taoyouth/2301505?source=drh