本站停止维护,已转移至laravel学习网;欢迎大家移步访问!

laravel guzzle爬虫实战 --进击篇(发送请求)

该页面提供了Guzzle的快速入门以及列子,如果你还没有安装Guzzle请前往 安装 页面。

你可以使用Guzzle的 GuzzleHttp\ClientInterface 对象来发送请求。

1.创建客户端

use GuzzleHttp\Client;
$client = new Client([
    // 默认请求的url
    'base_uri' => 'https://www.baidu.com/',
    // 默认请求时间,你可以任意设置
    'timeout'  => 2.0,
]);

Client对象可以接收一个包含参数的数组:

2.base_uri讲解

基URI用来合并到相关URI,可以是一个字符串或者UriInterface的实例,当提供了相关uri,将合并到基URI,简单的来说,就是一个url链接的拼合,那么我们来看一下例子:

// 我们实现来撞见一个基本的api
$client = new Client(['base_uri' => 'https://baidu.com/api/']);
// 这样我们会去请求的url为 https://baidu.com/api/test
$response = $client->request('GET', 'test');
// 这样我们会去请求的url为 https://baidu.com/root
$response = $client->request('GET', '/root');

ok,官网为我们提供了更加详细的拼合实例:

base_uriURIResult
http://foo.com/barhttp://foo.com/bar
http://foo.com/foo/barhttp://foo.com/bar
http://foo.com/foobarhttp://foo.com/bar
http://foo.com/foo/barhttp://foo.com/foo/bar
http://foo.comhttp://baz.comhttp://baz.com
http://foo.com/?barbarhttp://foo.com/bar

3.handler

  • 传输HTTP请求的(回调)函数。 该函数被调用的时候包含 Psr7\Http\Message\RequestInterface 以及参数数组,必须返回 GuzzleHttp\Promise\PromiseInterface ,成功时满足Psr7\Http\Message\ResponseInterface 。 handler 是一个构造方法,不能在请求参数里被重写。

  • (混合) 构造方法中传入的其他所有参数用来当作每次请求的默认参数。

4. Client对象的方法可以很容易的发送请求:

$response = $client->get('http://baidu.com/get');
$response = $client->delete('http://baidu.com/delete');
$response = $client->head('http://baidu.com/get');
$response = $client->options('http://baidu.com/get');
$response = $client->patch('http://baidu.com/patch');
$response = $client->post('http://baidu.com/post');
$response = $client->put('http://baidu.com/put');

你可以创建一个请求,一切就绪后将请求传送给client:

<?php
namespace App\Http\Controllers;
use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Console\Command;
class TestController extends Controller
{
    public function test()
    {
        $client = new Client(['base_uri' => 'https://baidu.com/']);
        $request = new Request('GET', 'https://baidu.com/');
        $response = $client->send($request, ['timeout' => 2]);
        dd($response);
}
}

这样,我们可以获取到我们请求返回的Response信息

Client对象为传输请求提供了非常灵活的处理器方式,包括请求参数、每次请求使用的中间件以及传送多个相关请求的基URI。你可以在 Handlers and Middleware 页面找到更多关于中间件的内容。

二. 异步请求

你可以使用Client提供的方法来创建异步请求:

$promise = $client->getAsync('http://httpbin.org/get');
$promise = $client->deleteAsync('http://httpbin.org/delete');
$promise = $client->headAsync('http://httpbin.org/get');
$promise = $client->optionsAsync('http://httpbin.org/get');
$promise = $client->patchAsync('http://httpbin.org/patch');
$promise = $client->postAsync('http://httpbin.org/post');
$promise = $client->putAsync('http://httpbin.org/put');

你也可以使用Client的 sendAsync() and requestAsync() 方法:

<?php
namespace App\Http\Controllers;
use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Console\Command;
class TestController extends Controller
{
    public function test()
    {
        $client = new Client(['base_uri' => 'https://baidu.com/']);
        $headers = ['X-Foo' => 'Bar'];
        $body = 'Hello!';
        $request = new Request('HEAD', 'http://baidu.com/', $headers, $body);
        $promise = $client->requestAsync('GET', 'http://baidu.com/');
        dd($request);
        dd($promise);
}
}

这些方法返回了Request和Promise对象,该对象实现了由 Guzzle promises library 提供的 Promises/A+ spec ,这意味着你可以使用 then() 来调用返回值,成功使用 Psr\Http\Message\ResponseInterface 处理器,否则抛出一个异常。

<?php
namespace App\Http\Controllers;
use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Console\Command;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;
class TestController extends Controller
{
    public function test()
    {
        $client = new Client(['base_uri' => 'https://baidu.com/']);
        $promise = $client->requestAsync('GET', 'https://baidu.com/');
        $promise->then(
            function (ResponseInterface $res) {
                echo $res->getStatusCode() . "\n";
            },
            function (RequestException $e) {
                echo $e->getMessage() . "\n";
                echo $e->getRequest()->getMethod();
            }
        );
        dd($promise);
}
}

三 . 并发请求

你可以使用Promise和异步请求来同时发送多个请求:

namespace App\Http\Controllers;
use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Console\Command;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Promise;
class TestController extends Controller
{
    public function test()
    {
        $client = new Client();
        // 创建一个请求列表
        $promises = [
            'baidu' => $client->getAsync('https://www.baidu.com/'),
            'jd'   => $client->getAsync('http://www.jd.com/'),
            'earnp'  => $client->getAsync('http://bbs.earnp.com/'),
        ];
        // 等待所有请求完成
        $results = Promise\unwrap($promises);
        // 查看请求结果
        $baidu = $results['baidu']->getHeader('Content-Length');
        $jd = $results['jd']->getHeader('Content-Length');
        $earnp = $results['earnp']->getHeader('Content-Length');
        dd($jd);
}
}

当你想发送不确定数量的请求时,可以使用 GuzzleHttp\Pool 对象:

<?php
namespace App\Http\Controllers;
use GuzzleHttp\Client;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Console\Command;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Promise;

class TestController extends Controller
{
    public function test()
    {
        $client = new Client();
        $requests = function ($total) {
            $uri = 'http://baidu.com';
            for ($i = 0; $i < $total; $i++) {
                yield new Request('GET', $uri);
            }
        };
        $pool = new Pool($client, $requests(100), [
            'concurrency' => 5,
            'fulfilled' => function ($response, $index) {
                // this is delivered each successful response
            },
            'rejected' => function ($reason, $index) {
                // this is delivered each failed request
            },
        ]);
        // Initiate the transfers and create a promise
        $promise = $pool->promise();
        // Force the pool of requests to complete.
        $promise->wait();
	}
}
转载请注明 :一沙网络原文出处:http://bbs.earnp.com/article/219
问题交流群 :562864481
0
打赏
发布时间 :2016-11-10 13:56:36
分享

0 个评论

    还没有评论,感觉来抢沙发吧!

要回复文章请先登录注册