php在多线程爬虫这块的确很单薄,但也是存在可行易实现的计划的。
实际框架:thinkphp5
要实现这个性能,须要装置两个包:
- jaeger/querylist:能够实现一些爬网页罕用的语法,比方xPath
- jaeger/querylist-curl-multi:实现多线程发动网络操作的包
querylist的长处是安装简单、无坑,在命令行和接口都能够应用。
相干文档:
http://www.querylist.cc/docs/...
http://www.querylist.cc/docs/...
实现步骤:
1.安装包:
composer require jaeger/querylistcomposer require jaeger/querylist-curl-multi
2.php文件:
use QL\QueryList;use QL\Ext\CurlMulti;//爬取列表public function spider(){ $urlPool = []; $startPage = 1; //从第几页开始爬取 $workerNum = 10; //并发执行的数量 $host = 'https://xxxxxx?page='; $nowPage = 1; //执行中用到的暂存计数器 while(1){ //生成要爬取的链接,每次循环打印$workerNum页数据 for($i=1;$i<=$workerNum;$i++){ $urlPool[] = $host.$nowPage; $nowPage++; } $ql = QueryList::use(CurlMulti::class); $ql->curlMulti($urlPool) // 每个工作胜利实现调用此回调 ->success(function (QueryList $ql,CurlMulti $curl,$r){ //此处能够用xpath语法获取到相应的数据 //也能够采纳别的模式来获取数据,可查阅文档 $data = $ql->find('#hits-list > div:nth-child(n) > div.header > div > a:nth-child(1)')->texts(); //打印下以后获取到的链接 和 解析到的数据 Log::write('Current url:'.$r['info']['url']); Log::write($data->all()); //若有简单逻辑,能够进行调用其余办法进行解决 SpiderService::getInstance()->insertToDb($data->all()); }) // 每个工作失败回调 ->error(function ($errorInfo,CurlMulti $curl){ echo "Current url:{$errorInfo['info']['url']} \r\n"; print_r($errorInfo['error']); //出错终止,跳出循环 throw new Exception("报错完结"); }) ->start([ // 最大并发数 'maxThread' => $workerNum, // 谬误重试次数 'maxTry' => 3, ]); //每次执行结束,重置链接池 $urlPool = []; }}