ThinkPHP5.1+swoole+QueryList實現(xiàn)異步爬取數(shù)據(jù)功能

先講下為什么要使用swoole異步任務,在項目中我們經(jīng)常會遇到執(zhí)行時間比較久的請求(上傳原叮,爬取等),讓用戶一直等待不是好的體驗拄衰,所以我們使用swoole異步請求,先返回‘執(zhí)行中’,等異步任務執(zhí)行完畢再修改狀態(tài)饵骨。
接下來我們來實現(xiàn)swoole在thinkphp 里的集成:
1.安裝swoole
推薦使用官網(wǎng)提供的安裝方式 安裝swoole擴展
2.安裝QueryList

composer require jaeger/querylist

文檔地址 querylist

3.在Tp5里自定義一個命令行類
在application下建立一個console文件夾用來存放自定義命令文件翘悉,然后在該文件夾下新建Crawler.php文件,編輯application目錄下的command.php文件
添加如下代碼

return [
    'app\console\Crawler',
];
深度截圖_選擇區(qū)域_20190920133914.png

編寫 Crawler.php

<?php

namespace app\Console;

use QL\QueryList;
use think\console\Command;
use think\console\Input;
use think\console\Output;


class Ceshi extends Command{
    protected $server;
    protected function configure()
    {
        //參考tp5自定義命令行手冊
        $this->setName('crawler:start')->setDescription('Start Crawler Server!');
    }

    protected function execute(Input $input, Output $output)
    {
        $serv = new \swoole_server('0.0.0.0',9502);//9502為swoole監(jiān)聽端口居触,可以自行設置
        $serv->set(array('task_worker_num' => 4));//異步進程數(shù)量 根據(jù)實際情況進行配置妖混,參照官網(wǎng)提供的方案
        $serv->on('connect', function ($serv, $fd){

        });
        $serv->on('receive', function($serv, $fd, $from_id,$data) {
            //投遞異步任務 $data為接口傳遞的參數(shù),接收參數(shù)做一些處理之后交給task
            echo'收到任務';
            $serv->task($data);
        });
        $serv->on('task', function ($serv, $task_id, $from_id, $data) {
            //接收receive傳遞的任務饼煞,進行執(zhí)行
            //本例中實現(xiàn)的是爬取京東商品任務 源葫,大家可以根據(jù)自身情況修改
            echo'執(zhí)行任務';
            $this->crawler($data);
        });
        $serv->on('finish', function ($serv, $task_id, $data) {

        });
        $serv->start();
    }

    /**
     * 采集商品數(shù)據(jù)
     * @param $activity_id
     * @return bool
     */
    private function crawler($activity_id)
    {
        //假設 $number 為京東活動id
        $number = 123456;
        $data = [];
        $limit = 1;//起始
        $ql = QueryList::getInstance();
        for (; ;) {
            $offset = $limit * 30 + 1;//偏移量
            //這個url是通過分析京東加載商品接口提取出來的,修改這幾個參數(shù)就能模擬分頁爬取到京東全部活動的商品
            $url = 'https://search.jd.com/s_new.php?activity_id=' . $number . '&vt=2&scc=1&page=' . $limit . '&s=' . $offset . '&scrolling=y&tpl=1_M';
            //這里使用了代理砖瞧,因為循環(huán)爬取的原因被京東檢測到了封了ip息堂,所以使用動態(tài)代理爬取,代理的使用根據(jù)代理服務商提供的api每個都不同块促,在本文不詳細介紹
            $crawler = $this->immediate($url);
            if ($crawler) {
                $query = [];
                //phpquery 的核心思想就是使用php像js一樣通過dom操作頁面
                //下面代碼的意思是 獲取頁面的html 找到class為gl-item的子元素荣堰,并遍歷(就是遍歷京東頁面展示的商品div)
                $ql->html($crawler)->find('.gl-item')->children()->map(function ($item) use (&$query, $number, $activity_id) {
                    $tags = '';
                    //找到標簽展示規(guī)律并提取
                    $item->find('.p-icons')->children()->map(function ($child_tag) use (&$tags) {
                        $tags .= $child_tag->html() . ',';
                    });
                    //找到商品價格展示規(guī)律并提取
                    $price = $item->find('.p-price>strong>i')->html();
                    if (!$price) {
                        $price = $item->find('.p-price>strong')->attrs('data-price')[0] ?? 0;
                    }
                    if ($price && $price > 0) {
                        //這里通過節(jié)點找到需要的數(shù)據(jù)和數(shù)據(jù)表對應存到mysql
                        $query[] = [
                            'activity_id' => $activity_id,
                            'activity_number' => $number,
                            'goods_number' => $item->find('.p-operate>a')->attrs('data-sku')[0] ?? '',
                            'title' => $item->find('.p-name-type-2>a>em')->text(),
                            'image' => 'http:' . $item->find('.p-img>a>img')->attrs('source-data-lazy-img')[0] ?? '',
                            'price' => $price,
                            'tags' => rtrim($tags, ','),
                            'shop_name' => $item->find('.p-shop>span>a')->html(),
                            'shop_number' => $item->find('.p-img>div')->attrs('data-venid')[0] ?? '',
                        ];

                    }
                });
                if (count($query)) {
                    foreach ($query as $k => $v) {
                        $data[] = $v;
                    }
                    $limit++;
                } else {
                    break;
                }
            }
            //盡量讓爬蟲等待一秒再執(zhí)行,避免內存溢出
            sleep(1);
        };
        //爬蟲功能結束之后及時釋放內存
        $ql->destruct();
        //.......
        //接下來把數(shù)據(jù)存進mysql中就大功告成啦
    }

}

4.寫一個接口去調用異步任務

public function swoole_task(Request $request){
        $type = $request->param('type');
        $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
        $ret = $client->connect("服務器ip", 9502);
        if(empty($ret)){
            return 'FAIL';
        } else {
            $client->send($type);//提交任務到crawler.php 處理 我是傳參$type實現(xiàn)不同的異步任務調用
            return 'SUCCESS';
        }
    }

5.進入tp5 項目根目錄執(zhí)行命令

php think crawler:start//通常用于調試

讓swoole監(jiān)聽命令以守護進程方式運行(服務器)

php think crawler:start &

6.執(zhí)行上面寫好的調用接口swoole_task 可以在你想用的任何地方調用
7.效果


深度截圖_選擇區(qū)域_20190920142220.png

本文提供的方法僅供參考竭翠,實例并不能直接執(zhí)行振坚,需要大家理解工作原理后結合自身項目進行使用

8.推薦一下本文使用技術在項目中的應用,微信搜索‘東東小賣部’斋扰,每天會爬取最新的京東滿減打折活動渡八,
通過算法湊成滿減之后將商品組合返回給用戶,親身體驗過非常不錯传货,這個項目對于喜歡網(wǎng)購的朋友們來說絕對會帶給你非常棒的體驗屎鳍。
大家要是覺得本文有幫助的話,幫忙關注下公眾號分享給身邊的人问裕,不許白嫖哦逮壁,十分感謝


微信圖片_20190920104620.jpg

微信圖片_20190920104614.jpg

d19aaddda144ad34e5809b91dfa20cf431ad8526.jpg

e37546d98d1001e9f3030819b70e7bec54e79726.jpg
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市粮宛,隨后出現(xiàn)的幾起案子窥淆,更是在濱河造成了極大的恐慌卖宠,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忧饭,死亡現(xiàn)場離奇詭異扛伍,居然都是意外死亡,警方通過查閱死者的電腦和手機眷昆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門蜒秤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人亚斋,你說我怎么就攤上這事∪撂玻” “怎么了帅刊?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長漂问。 經(jīng)常有香客問我赖瞒,道長,這世上最難降的妖魔是什么蚤假? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任栏饮,我火速辦了婚禮,結果婚禮上磷仰,老公的妹妹穿的比我還像新娘袍嬉。我一直安慰自己,他們只是感情好灶平,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布伺通。 她就那樣靜靜地躺著,像睡著了一般逢享。 火紅的嫁衣襯著肌膚如雪罐监。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天瞒爬,我揣著相機與錄音弓柱,去河邊找鬼。 笑死侧但,一個胖子當著我的面吹牛矢空,可吹牛的內容都是我干的。 我是一名探鬼主播俊犯,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼妇多,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了燕侠?” 一聲冷哼從身側響起者祖,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤立莉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后七问,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜓耻,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年械巡,在試婚紗的時候發(fā)現(xiàn)自己被綠了刹淌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡讥耗,死狀恐怖有勾,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情古程,我是刑警寧澤蔼卡,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站挣磨,受9級特大地震影響雇逞,放射性物質發(fā)生泄漏。R本人自食惡果不足惜茁裙,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一塘砸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晤锥,春花似錦掉蔬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至霜威,卻和暖如春谈喳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背戈泼。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工婿禽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人大猛。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓扭倾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親挽绩。 傳聞我的和親對象是個殘疾皇子膛壹,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容