#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 с небезопасного на безопасный.