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 = [];  }}