php-html-парсер, как следить за перенаправлениями

#php #html-parsing

Вопрос:

https://github.com/paquettg/php-html-parser Кто-нибудь знает, как следить за перенаправлениями в этой библиотеке? Например:

 require "vendor/autoload.php";
use PHPHtmlParserDom;
$dom = new Dom;
$dom->loadFromUrl($html);
 

Комментарии:

1. Самым тривиальным способом — используя другую библиотеку, чтобы сделать запрос и получить конечный результат, а затем используя loadStr вместо этого …

2. Или передайте свой собственный ClientInterface loadFromUrl вызов и используйте тот, который настроен на автоматическое отслеживание перенаправлений.

3. Как указывает @CBroe, они полагаются на клиент Guzzle , который может быть создан и передан, чтобы разрешить перенаправление, что является поведением по умолчанию

4. Но как это сделать? @hppycoder Можешь привести мне пример?

5. О, это так весело! Это не так прямолинейно, как мы думали, и я сейчас работаю над этим. Я подробно расскажу ниже о своем ответе

Ответ №1:

Версии:

  • жрать / жрать: «7.2.0»
  • paquettg/php-html-парсер: «3.1.1»

Почему библиотека изначально не разрешает перенаправление?

loadFromUrl Метод имеет следующую подпись (на данный момент 3.1.1)

     public function loadFromUrl(string $url, ?Options $options = null, ?ClientInterface $client = null, ?RequestInterface $request = null): Dom
    {
        if ($client === null) {
            $client = new Client();
        }
        if ($request === null) {
            $request = new Request('GET', $url);
        }

        $response = $client->sendRequest($request);
        $content = $response->getBody()->getContents();

        return $this->loadStr($content, $options);
    }
 

Глядя на строчку $response = $client->sendRequest($request); , которая идет к клиенту Гузла — https://github.com/guzzle/guzzle/blob/master/src/Client.php#L131

 /**
* The HttpClient PSR (PSR-18) specify this method.
*
* @inheritDoc
*/
public function sendRequest(RequestInterface $request): ResponseInterface
{
   $options[RequestOptions::SYNCHRONOUS] = true;
   $options[RequestOptions::ALLOW_REDIRECTS] = false;
   $options[RequestOptions::HTTP_ERRORS] = false;

   return $this->sendAsync($request, $options)->wait();
}
 

Это $options[RequestOptions::ALLOW_REDIRECTS] = false; автоматически отключит перенаправление. Независимо от того, что вы передадите Клиенту или запросите, он автоматически отключит перенаправление.

Как следить за перенаправлениями с помощью библиотеки

Заметив, что метод loadFromUrl сделает запрос и получит ответ, затем loadStr мы будем имитировать то же самое, но использовать жадность (поскольку это зависимость библиотеки).

 <?php
// Include the autoloader
use GuzzleHttpClient;
use GuzzleHttpExceptionGuzzleException;
use PHPHtmlParserDom;

include_once("vendor/autoload.php");

$client = new Client();
try {
    // Showing the allow_redirects for verbosity sake. This is on by default with GuzzleHTTP clients.
    $request = $client->request('GET', 'http://theeasyapi.com', ['allow_redirects' => true]);

    // This would work exactly the same
    //$request = $client->request('GET', 'http://theeasyapi.com');
} catch(GuzzleException $e) {
    // Probably do something with $e
    var_dump($e->getMessage());
    exit;
}

$dom = new Dom();
$domExample = $dom->loadStr($request->getBody()->getContents());
foreach($domExample->find('a') as $link) {
    var_dump($link->text);
}
 

Приведенный выше код создаст экземпляр нового клиента Guzzle и отправит запрос на URL-адрес, разрешающий перенаправление. Веб-сайт, используемый в этом примере, является сайтом, который будет перенаправлять 301 с небезопасного на безопасный.