Heim  >  Artikel  >  Backend-Entwicklung  >  Laravel 下使用 Guzzle 编写多线程爬虫实战

Laravel 下使用 Guzzle 编写多线程爬虫实战

WBOY
WBOYOriginal
2016-06-23 13:06:081749Durchsuche

说明

Guzzle库是一套强大的 PHP HTTP 请求套件。

本文重点演示如何使用 Guzzle 发起多线程请求。

参考

  • Github 官方用户接口文档
  • Guzzle 并发请求文档
  • Laravel LTS 5.1 - Artisan 文档

创建命令

1. 运行命令行创建命令

php artisan make:console MultithreadingRequest --command=test:multithreading-request

2. 注册命令

编辑 app/Console/Kernel.php,在 $commands 数组中增加:

Commands\MultithreadingRequest::class,

3. 测试下命令

修改 app/Console/Commands/MultithreadingRequest.php文件,在 handle方法中增加:

$this->info('hello');

输出:

$ php artisan test:multithreading-requesthello

4. 安装 Guzzle

composer require guzzlehttp/guzzle "6.2"

直接贴代码

一份可运行的代码胜过千言万语呀。

下面代码是 app/Console/Commands/MultithreadingRequest.php里的内容:

<?php namespace App\Console\Commands;use GuzzleHttp\Client;use GuzzleHttp\Pool;use GuzzleHttp\Psr7\Request;use GuzzleHttp\Exception\ClientException;use Illuminate\Console\Command;class MultithreadingRequest extends Command{    private $totalPageCount;    private $counter        = 1;    private $concurrency    = 7;  // 同时并发抓取    private $users = ['CycloneAxe', 'appleboy', 'Aufree', 'lifesign',                        'overtrue', 'zhengjinghua', 'NauxLiu'];    protected $signature = 'test:multithreading-request';    protected $description = 'Command description';    public function __construct()    {        parent::__construct();    }    public function handle()    {        $this->totalPageCount = count($this->users);        $client = new Client();        $requests = function ($total) use ($client) {            foreach ($this->users as $key => $user) {                $uri = 'https://api.github.com/users/' . $user;                yield function() use ($client, $uri) {                    return $client->getAsync($uri);                };            }        };        $pool = new Pool($client, $requests($this->totalPageCount), [            'concurrency' => $this->concurrency,            'fulfilled'   => function ($response, $index){                $res = json_decode($response->getBody()->getContents());                $this->info("请求第 $index 个请求,用户 " . $this->users[$index] . " 的 Github ID 为:" .$res->id);                $this->countedAndCheckEnded();            },            'rejected' => function ($reason, $index){                $this->error("rejected" );                $this->error("rejected reason: " . $reason );                $this->countedAndCheckEnded();            },        ]);        // 开始发送请求        $promise = $pool->promise();        $promise->wait();    }    public function countedAndCheckEnded()    {        if ($this->counter < $this->totalPageCount){            $this->counter++;            return;        }        $this->info("请求结束!");    }}

运行结果:

$ php artisan test:multithreading-request请求第 5 个请求,用户 zhengjinghua 的 Github ID 为:3413430请求第 6 个请求,用户 NauxLiu 的 Github ID 为:9570112请求第 0 个请求,用户 CycloneAxe 的 Github ID 为:6268176请求第 1 个请求,用户 appleboy 的 Github ID 为:21979请求第 2 个请求,用户 Aufree 的 Github ID 为:5310542请求第 3 个请求,用户 lifesign 的 Github ID 为:2189610请求第 4 个请求,用户 overtrue 的 Github ID 为:1472352请求结束!

注意请求是同时发送过去的,因为 concurrency并发设置了 7,所以 7 个请求同时发送,只不过接收到返回的时间点不一样。

完。

:beers: :beers: :beers:

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:关于discuz的模板文件调用SQL的问题Nächster Artikel:求源代码