使用phpQuery採集文章或者其餘數據...

//1.首先,你得建立一張表,叫採集表,,若是你只是簡單地幾條連接,能夠手動錄入,若是比較多的話,就須要本身用方法,寫個for循環,匹配一些規則生成url,存儲在表內.php

CREATE TABLE `cp_lottery_articles_gather_list` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `site_id` int(11) NOT NULL COMMENT '站點id',
  `lottery_id` int(11) DEFAULT NULL COMMENT '彩票id',
  `type_id` int(11) DEFAULT NULL COMMENT '文章欄目類型id',
  `category_id` int(11) DEFAULT NULL COMMENT '資訊欄目ID',
  `lottery_name` varchar(255) DEFAULT NULL COMMENT '關聯彩票名稱',
  `type_name` varchar(255) DEFAULT NULL COMMENT '類型名稱',
  `link` varchar(255) NOT NULL COMMENT '採集連接',
  `total_page` int(11) DEFAULT '1' COMMENT '總採集頁數',
  `now_page` int(11) DEFAULT '1' COMMENT '最大頁數',
  `error` int(11) DEFAULT '0' COMMENT '錯誤次數',
  `del` int(11) DEFAULT '0' COMMENT '是否刪除(-1爲刪除,0爲默認)',
  `status` int(11) DEFAULT '1' COMMENT '狀態值(1爲待採集,2爲採集ok)',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=147 DEFAULT CHARSET=utf8;

這是表數據html

2.開始進入代碼,首先寫一個獲取採集連接的方法.  將連接數據放入全局變量,好處是,當你在使用curlMulity多線程採集的時候,線程內部,惟一的判斷標準是你的連接,也就是url,,而後你怎麼去判斷哪一次採集的數據,是屬於哪一條連接的呢?如何根據連接定位到ID呢? 這個時候這個$GLOBAS就起大做用了,能夠在線程內部去調用globas變量,而後字符串搜索連接,這樣就找到對應的連接信息和ID了.sql

//獲取批量的待採集列表頁連接,並將鏈接放到全局變量$GLOBALS
    private function get_list_links(){
        //條件:站點ID爲500彩票網,狀態爲1(待採集)
        $where=[
            "site_id"=>$this->site_id,
            "status"=>1
        ];

        $list=db("lottery_articles_gather_list")
            ->where($where)
            ->order("id","asc")
            ->limit(0,10)
            ->select();

        if(empty($list)){
            return false;
        }

        //對後綴進行拼接.若是nowpage爲1,則爲index.shtml
        foreach ($list as $k=>$v){
            $suffix="index".$v['now_page'].".shtml";
            if($v['now_page']=="1"){
                $suffix="index.shtml";
            }
            $list[$k]["link"]=$v["link"].$suffix;

        }

        //放到全局變量裏面去
        $GLOBALS['wubai_gather_list']=$list;
        return $list;

    }

3.(重要)採集方法.數組

大體過程就是:瀏覽器

3.1.先將globas裏面的連接二維數據取出來,而後經過array_column,只去其中的link字段,獲取到10條只包含連接字符串的一維數組緩存

3.2 初始化queryList插件,而後使用curlMulity,進行採集.網絡

3.3 在內部,每次採集,根據規則,獲取到你想要的數據,對數據進行處理後.一樣放到$globas全局變量中多線程

3.4 對於沒采集到的,就不用管了..併發

//採集列表開始
private function gather_list_do(){
    //獲取採集列表
    $link_list=$GLOBALS["wubai_gather_list"];
    //得到一維數組
    $links=array_column($link_list,"link");

    //執行採集
    $ql=QueryList::getInstance();
    $ql->use(CurlMulti::class);

    $opt=[
        CURLOPT_TIMEOUT=> 5,
        CURLOPT_CONNECTTIMEOUT=>5,
        CURLOPT_RETURNTRANSFER=>1,//不輸出數據
        CURLOPT_SSL_VERIFYPEER=>0,//https驗證
        CURLOPT_FOLLOWLOCATION=>0,//不重定向
        CURLOPT_USERAGENT=>$_SERVER['HTTP_USER_AGENT'],
        CURLOPT_AUTOREFERER=>0,
        CURLOPT_ENCODING=>'gzip,deflate',
        CURLOPT_HEADER=>0,
    ];



    $GLOBALS['all_data']=[];
    $ql->curlMulti($links)
        ->success(function (QueryList $ql,CurlMulti $curl,$r){
            //開始獲取數據
            echo $r['info']['url'].'採集數據中<br/>';
            //分片規則
            $range="#news_list>ul li";
            //採集元素規則
            $rules=[
                "date"=>[".newsdate","text"],
                "title"=>["a","text"],
                "link"=>["a","href"],
            ];


            $data=$ql
                ->rules($rules)
                ->encoding('UTF-8','GB2312')->removeHead()
                ->range($range)
                ->queryData();

            echo "採集完成<br/>";
            if(!empty($data)){
                echo $r['info']['url'].'成功獲取數據<br/>';
                //成功採集的數據,及其連接  放入到公共變量內
                $GLOBALS['all_data'][]=[
                    "link"=>$r['info']['url'],
                    "data"=>$data
                ];
            }

            echo "釋放內存----------------<br/>";
            //釋放內存
            $ql->destruct();

        })->error(function ($errorInfo,CurlMulti $curl,$r){
            //跳過
        })->start([
            // 最大併發數,這個值能夠運行中動態改變。
            'maxThread' => 5,
            // 觸發curl錯誤或用戶錯誤以前最大重試次數,超過次數$error指定的回調會被調用。
            'maxTry' => 1,
            // 全局CURLOPT_*
            'opt' =>$opt,
            // 緩存選項很容易被理解,緩存使用url來識別。若是使用緩存類庫不會訪問網絡而是直接返回緩存。
            'cache' => ['enable' => false, 'compress' => false, 'dir' => null, 'expire' =>86400, 'verifyPost' => false]
        ]);


}

4.最後將$globas裏面的數據,也就是採集到的數據,進行入庫處理..並對採集連接表,也進行處理..curl

4.1若是全鏈爲空,那麼將全部的連接now_page(當前採集頁碼),進一位..

4.2循環數據,定位連接,插入文章詳情表,,更新採集連接表

//設置文章列表數據
    private function set_arc_detail(){
        $all_data=$GLOBALS['all_data'];

        //若是是空數組,將全部的當前page+1,跳過
        if(empty($all_data)){
            foreach ($GLOBALS['wubai_gather_list'] as $k=>$v){
                $now_page=$v['now_page']+1;
                db("lottery_articles_gather_list")
                    ->where(["id"=>$v['id']])
                    ->update(['now_page'=>$now_page]);
            }

            return true;
        }


        //採集連接列表
        $gather_links=array_column($GLOBALS["wubai_gather_list"],"link");

        //1.定義變量接受數據
        $articles_save_data=[];
        $gather_links_save_data=[];




        foreach ($all_data as $k=>$v){
            //2.查詢當前的每個url在原始採集鏈中的定位
            $key=array_search($v['link'],$gather_links);
            //找到這個url->對應的lottery_articles_gather_list對應的數據
            $link_info=$GLOBALS['wubai_gather_list'][$key];

            //3.準備lottery_articles表須要的保存的數據
            foreach ($v["data"] as $k2=>$v2){
                //若是標題或者連接爲空,跳過本次數據.
                if(strlen($v2["title"])==""||$v2["link"]==""){
                    continue;
                }
                //組裝數據
                $data=[
                    "site_id"=>$this->site_id,
                    "lottery_id"=>$link_info["lottery_id"],
                    "category_id"=>$link_info["category_id"],
                    "type_id"=>$link_info["type_id"],
                    "type_name"=>$link_info["type_name"],
                    "category_name"=>db("lottery_articles_category")->where(["id"=>$link_info['category_id']])->cache()->value("name"),
                    "arc_link"=>$v2['link'],
                    "title"=>$v2["title"],
                    "keywords"=>"",
                    "description"=>"",
                    "content"=>"",
                    "create_time"=>strtotime($v2["date"]),
                    "create_time_html"=>$v2["date"],
                    "post_time"=>$_SERVER['REQUEST_TIME'],
                    "order"=>"0",
                    "hot"=>"0",
                    "status"=>"1"
                ];
                $articles_save_data[]=$data;

            }



            //4.準備lottery_articles_gather_list採集連接表,須要更新的數據
            $gather_links_data=[
                "id"=>$link_info['id'],
                "now_page"=>$link_info["now_page"]+1,
            ];
            //若是當前採集頁>=總頁碼,此條連接採集結束
            if($link_info['now_page']>=$link_info['total_page']){
                $gather_links_data["status"]=2;
            }
            $gather_links_save_data[]=$gather_links_data;


        }



        //5.執行插入,和更新操做.
        $arc_res_count=model("LotteryArticles")->insert_all_data($articles_save_data);

        $lists_up_count=0;
        if($arc_res_count>0){
            $lists_up_res=model("LotteryArticlesGatherList")->saveAll($gather_links_save_data);
            $lists_up_count=count($lists_up_res);
        }


        //6.輸出結果
        echo "總採集文章數量成功插入條數爲:{$arc_res_count}條<br/>";
        echo "總採集連接修改數量爲:{$lists_up_count}條<br/>";

    }



//處理字符串,只獲取字符串裏面的數字
    private function get_number($str){
        return  preg_replace('/([\x80-\xff]*)/i','',$str);
    }

5.最後用一個方法,對這幾個方法,進行調用,循環....就這樣,打開瀏覽器,就讓他一直採集成功,跳轉....就行了..雖然方法比較笨拙..

也能夠採用定時任務,去用命令行執行php文件的方式,定時採集..

private $site_id=2;

    //採集全部列表頁
    public function gather_all_list(){
        //獲取採集的url列表
        $link_list=$this->get_list_links();

        //獲取採集的數據集
        $this->gather_list_do();

        //處理採集的數據集合
        $this->set_arc_detail();

        $this->success("wubai_arc/gather_all_list");
    }

 

 

//11.7日補充更新

能夠採用命令行的形式先跑一遍

而後若是須要天天都採集,可使用定時任務+php命令行採集

注意:命令行採集的時候,將 CURLOPT_USERAGENT=>$_SERVER['HTTP_USER_AGENT'],將這個配置去掉,否則就會報錯..

至於怎麼使用定時+命令行採集,能夠看這一篇

https://my.oschina.net/laobia/blog/3121944

相關文章
相關標籤/搜索