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

WBOY
Release: 2016-06-23 13:06:08
Original
1751 people have browsed it

说明

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

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

参考

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

创建命令

1. 运行命令行创建命令

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

2. 注册命令

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

Commands\MultithreadingRequest::class,
Copy after login

3. 测试下命令

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

$this->info('hello');
Copy after login

输出:

$ php artisan test:multithreading-requesthello
Copy after login

4. 安装 Guzzle

composer require guzzlehttp/guzzle "6.2"
Copy after login

直接贴代码

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

下面代码是 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("请求结束!");    }}
Copy after login

运行结果:

$ 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请求结束!
Copy after login

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

完。

:beers: :beers: :beers:

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template