站三界导航
首页 TP代码简单记录thinkphp5使用Querylist插件做采集

简单记录thinkphp5使用Querylist插件做采集

  • TP代码
  • 来源:站三界导航
  • 152阅读
  • 2022-09-29

最近公司需要做一个信息发布网站,任务分配下来之后确定我来主导这个项目。由于之前做小说采集网站的时候多用的是CMS自带的采集系统,但是本人实在不怎么感冒cms,所以在网上查看了一些资料,很神奇的找到了Querylist这个东西,今天就将我昨晚这次项目的里程分享一下。

首先,querylist官网(http://www.querylist.cc),直接点击文档走起。

大概看了一下,可以满足我的需求。okay,thinkphp5框架搭起来,使用composer安装querylist,安装之后本地出现gaegar文件夹,进去之后就会看到querylist了。至此,完成了安装的步骤啦,就是这么简单!!!

接下来就是使用Querylist类啦,一步一步来走:

首先引入类

use QL\QueryList;

然后重点

        $html = "http://www.***.com";
        //选择大的区域
        $selector = "body";
        //获取当前所选区域html
        $content=QueryList::get($html)->find($selector)->html();
        //最外层规则筛选
        $rules = array(
            'plist' => ['dt','html']
        );
        //获取分类数据、处理/采集数据
        $data = $this->dealData($content,$rules);

$html是你要采集的目标站点,$content是获取到的html页面源码,$rules是即将要用的筛选规则。主要看一下处理数据的方法dealData();

public function dealData($content,$rules){
        $data = QueryList::html($content)->rules($rules)->range('')->queryData(function ($item){
            $item = QueryList::html($item)->rules(array(
                'title' => array('a','text'),
                'original_link' =>array('a','href')
            ))->range('')->queryData();
            return $item;
        });
        return $data;
    }

该方法中由于我要采集的目标站需要两层进去,所以又写了一次内部回调。将之前获取到的页面源码$content放入html()方法中去,使用rules()方法匹配dt标签中的html源码,range()方法是分片的,我这里没有用到,就留空,但是这个方法一定要写在这儿。在回调中,将之前获取到的html源码定在在$item中,然后进行二次rule规则筛选,将原站中的标题与链接采集到,此时的$item中就已经保存了我们想要的数据了,然后我们就可以将数据存库或是做其他处理了。

至此,一次简单的采集就完成了。

后附多线程采集的源码,原理与上面一样,需要注意的是,多线程采集时,需要引入对应的类,看下,如果大家有需要的话,我会再写一篇关于querylist多线程采集的文章。

use QL\QueryList;
use QL\Ext\CurlMulti;
use think\Db;

class Gather extends Admin
{
    /**
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * 采集文章信息
     * @author lyf
     * @date 2019-5-10
     */
    public function index(){
        $param=$this->request->get();
        $ql = QueryList::getInstance();
        $ql->use(CurlMulti::class);

        $htmls = array();
        $map['status'] = 0;
        $html = Db::name('city_cate_url')
            ->where($map)
            ->order("id","ASC")
            ->limit("0","10")
            ->select();
        foreach ($html as $item){
            $url = explode('/',$item['url']);
            $link = explode('.',$url[3]);
            $htmls[] = $url[0].'//'.$url[2].'/'.$link[0].'P'.$item['page'].'.'.$link[1];
        }
        $data = $this->gather($htmls,$ql);

        $ids=array_column($html,"id");
        $res_list=db("city_cate_url")
            ->where("id","in",$ids)
            ->where('status','-1')
            ->select();
        $k=0;
        if($htmls){
            $k++;
            if($res_list){
                $this->success("正在采集第{$k}次","gather/index","",60);
            }else{
                $this->success("正在采集第{$k}次","gather/index","",30);
            }
        }else{
            $this->success("采集成功");
        }

    }

    /**
     * @param $html
     * @param $city_name
     * @param $cate_name
     * @param $num
     * @return string
     * 采集列表信息
     * @author lyf
     * @date 2019-5-8
     */
    public function gather($html,$ql){
        $ql->curlMulti($html)->success(function (QueryList $ql,CurlMulti $curl,$r){
//            echo $r['info']['url'];echo "<br>";
            //初始化
            $content1 = '';
            $content2 = '';
            //获取城市ID
            $city = explode('/',$r['info']['url']);
            $cityId = $this->getCityId($city[0].'//'.$city[2].'/');

            $msg = '';
            $selector1 = "#main";
            $selector2 = "tbody";
            try{
                $content1=$ql->get($r['info']['url'])->find($selector1)->html();
                $content2=$ql->get($r['info']['url'])->find($selector2)->html();

            }catch(\Exception $e) {

            }
            $rules = [
                'title' => ['.t>div>a','title'],
                'original_link' => ['.t>div>a','href'],
                'img' => ['.i>a>img','src'],
                'brief' => ['.t>div','html','-#wrapv1'],
                'price' => ['.p','text'],
                'date' => ['.u','text']
            ];

            if($content1&&$content2){
                //处理数据信息
                $data = $this->dealData($content2,$rules,$ql,$cityId,$r['info']['url']);
                //数据入库
                if($data){
                    $res = $this->saveData($data,$r['info']['url']);
                }
            }
            else if($content1&&!$content2){
                $this->endNow($r['info']['url'],$status='1');
            }else{
                $this->endNow($r['info']['url'],$staus='-1');
            }
            $ql->destruct();

        })->start([
            // 最大并发数,这个值可以运行中动态改变。
            'maxThread' => 10,
            // 触发curl错误或用户错误之前最大重试次数,超过次数$error指定的回调会被调用。
            'maxTry' => 3,
            // 全局CURLOPT_*
            'opt' => [
                CURLOPT_TIMEOUT => 10,
                CURLOPT_CONNECTTIMEOUT => 1,
                CURLOPT_RETURNTRANSFER => true
            ]
        ]);
    }


大家有什么不满意的地方,可以随时指正,也希望大家多多包涵。有问题随时可以私我,看到的话一定会回复哒

本文结束
本文来自投稿,不代表站三界导航立场,如若转载,请注明出处:https://www.zhansanjie.com/article/details/10645.html

版权声明:

1、本文系转载,版权归原作者所有,旨在传递信息,不代表看本站的观点和立场。

2、本站仅提供信息发布平台,不承担相关法律责任。

3、若侵犯您的版权或隐私,请联系本站管理员删除。

4、本文由会员转载自互联网,如果您是文章原创作者,请联系本站注明您的版权信息。

分享
站三界导航
本站声明:本站严格遵守国家相关法律规定,非正规网站一概不予收录。本站所有资料取之于互联网,任何公司或个人参考使用本资料请自辨真伪、后果自负,站三界导航不承担任何责任。在此特别感谢您对站三界导航的支持与厚爱。