【问题标题】:Sending multiple goutte requests asynchronously异步发送多个 goutte 请求
【发布时间】:2023-10-08 14:20:01
【问题描述】:

这是我正在使用的代码

require_once 'goutte.phar';
use Goutte\Client;
$client = new Client();
for($i=0;$i<10;$i++){
     $crawler = $client->request('GET', 'http://website.com');
     echo '<p>'.$crawler->filterXpath('//meta[@property="og:description"]')->attr('content').'</p>';
     echo '<p>'.$crawler->filter('title')->text().'</p>';
}

这可行,但需要大量时间来处理?有什么方法可以更快。

【问题讨论】:

    标签: php guzzle goutte


    【解决方案1】:

    首先,您的代码示例没有任何异步内容。这意味着您的应用程序将按顺序执行获取请求,等待响应,解析响应然后循环返回。

    虽然 Goutte 在内部使用 Guzzle,但它没有使用 Guzzles 的异步功能。

    要真正使您的代码异步,您需要参考 Guzzle 文档:

    您上面的代码示例会产生如下结果:

    require 'vendor/autoload.php' //assuming composer package management.
    
    $client = new GuzzleHttp\Client();
    
    $requests = [
        $client->createRequest('GET', $url1),
        $client->createRequest('GET', $url2),
        $client->createRequest('GET', $url3),
        $client->createRequest('GET', $url4),
        $client->createRequest('GET', $url5),
        $client->createRequest('GET', $url6),
        $client->createRequest('GET', $url7),
        $client->createRequest('GET', $url8),
        $client->createRequest('GET', $url9),
        $client->createRequest('GET', $url10),  
    ];
    
    $options = [
        'complete' => [
            [
                'fn' => function (CompleteEvent $event) {
                    $crawler = new Symfony\Component\DomCrawler\Crawler(null, $event->getRequest()->getUrl());
                    $crawler->addContent($event->getResponse->getBody(), $event->getResponse()->getHeader('Content-Type'));
                    echo '<p>'.$crawler->filterXpath('//meta[@property="og:description"]')->attr('content').'</p>';
                    echo '<p>'.$crawler->filter('title')->text().'</p>';
                },
                'priority' => 0,    // Optional
                'once'     => false // Optional
            ]
        ]
    ];
    
    $pool = new GuzzleHttp\Pool($client, $requests, $options);
    
    $pool->wait();
    

    【讨论】:

    • 嗨,肖恩,谢谢你的解释。我得到了 `Uncaught exception 'InvalidArgumentException' with message` 错误。
    • @PriyaRawat - 当您提供的信息与所提供的信息一样少时,要求我解决所描述的错误是不公平或不合理的。话虽如此,我冒昧地猜测您正在尝试使用 Goutte 附带的 Guzzle 版本。根据您使用的 Goutte 版本,您(可能)不会拥有正确版本的 Guzzle。确保您的 composer.json 文件列出 guzzlehttp\guzzle 和 symfony\dom-crawler。