Очистка веб-сайта с помощью Goutte зависает до истечения времени ожидания на определенном сайте

#php #laravel #web-scraping #timeout #goutte

#php #laravel #веб-очистка #тайм-аут #goutte

Вопрос:

Я играю с Goutte и не могу заставить его подключиться к определенному веб-сайту. Все остальные URL-адреса, похоже, работают отлично, и я изо всех сил пытаюсь понять, что мешает ему подключиться. Он просто зависает, пока не истечет время ожидания через 30 секунд. Если я удалю время ожидания, то же самое произойдет через 150 секунд.

Ключевые моменты, на которые следует обратить внимание:

  • Это время ожидания / зависания происходит только на tesco.com это я нашел до сих пор. asda.com , google.com , etc работают нормально и возвращают результат.
  • Сайт мгновенно загружается в веб-браузере (Chrome) (не связан с IP или ISP).
  • Я получаю результат, возвращаемый нормально, если я делаю запрос GET в Postman на тот же URL.
  • Похоже, что это не связано с агентом пользователя.
 <?php

namespace AppHttpControllers;

use GoutteClient;
use GuzzleHttpClient as GuzzleClient;

class ScraperController extends Controller
{
    public function scrape()
    {
        $goutteClient = new Client();

        $goutteClient->setHeader('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36');

        $guzzleClient = new GuzzleClient(array(
            'timeout' => 30,
            'verify' => true,
            'debug' => true,
        ));
        $goutteClient->setClient($guzzleClient);
        $crawler = $goutteClient->request('GET', 'https://www.tesco.com/');

        dump($crawler);

        /*$crawler->filter('.result__title .result__a')->each(function ($node) {
            dump($node->text());
        });*/

    }
}
 

Это вывод «debug», включающий ошибку:

 * Trying 104.123.91.150:443... * TCP_NODELAY set * Connected to www.tesco.com (104.123.91.150) port 443 (#0) * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: C=GB; L=Welwyn Garden City; jurisdictionC=GB; O=Tesco PLC; businessCategory=Private Organization; serialNumber=00445790; CN=www.tesco.com * start date: Feb 4 11:09:23 2020 GMT * expire date: Feb 3 11:39:21 2022 GMT * subjectAltName: host "www.tesco.com" matched cert's "www.tesco.com" * issuer: C=US; O=Entrust, Inc.; OU=See www.entrust.net/legal-terms; OU=(c) 2014 Entrust, Inc. - for authorized use only; CN=Entrust Certification Authority - L1M * SSL certificate verify ok. > GET / HTTP/1.1 Host: www.tesco.com user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 * old SSL session ID is stale, removing * Operation timed out after 30001 milliseconds with 0 bytes received * Closing connection 0
 
 GuzzleHttpExceptionConnectException
cURL error 28: Operation timed out after 30001 milliseconds with 0 bytes received (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
http://localhost/scrape
 

Кто-нибудь может понять, почему я вообще не получаю ответа?

Ответ №1:

Удалось решить эту проблему, добавив еще несколько заголовков:

 <?php

namespace AppHttpControllers;

use GoutteClient;
use GuzzleHttpClient as GuzzleClient;

class ScraperController extends Controller
{
    public function scrape()
    {
        $goutteClient = new Client();

        $goutteClient->setHeader('accept', 'text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9');
        $goutteClient->setHeader('accept-encoding', 'gzip, deflate, br');
        $goutteClient->setHeader('accept-language', 'en-GB,en-US;q=0.9,en;q=0.8');
        $goutteClient->setHeader('upgrade-insecure-requests', '1');
        $goutteClient->setHeader('user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36');
        $goutteClient->setHeader('connection', 'keep-alive');

        $guzzleClient = new GuzzleClient(array(
            'timeout' => 5,
            'verify' => true,
            'debug' => true,
            'cookies' => true,
        ));
        $goutteClient->setClient($guzzleClient);
        $crawler = $goutteClient->request('GET', 'https://www.tesco.com/');

        dump($crawler);

        /*$crawler->filter('.result__title .result__a')->each(function ($node) {
            dump($node->text());
        });*/
    }
}