Viele Male, wenn kriechen wir auf Probleme stoßen, wo Inhalte, die mit Javascript erzeugt werden und kratzig ist daher auf der Seite gerendert wird nicht in der Lage, dafür zu kriechen (z. B. AJAX-Anfragen, jQuery)Wie krieche ich mit PHP Goutte und Guzzle, wenn Daten von Javascript geladen werden?
Antwort
Guzzle (die Goutte intern verwendet) ist ein HTTP-Client. Daher wird JavaScript-Inhalt nicht analysiert oder ausgeführt. Javascript-Dateien, die sich außerhalb des angeforderten Endpunkts befinden, werden nicht heruntergeladen.
Je nach Ihrer Umgebung, nehme ich es möglich wäre, PHPv8 (eine PHP-Erweiterung, die die Google-V8-JavaScript-Engine bettet) zu nutzen und eine benutzerdefinierte handler/middleware auszuführen, was Sie wollen.
Dann wiederum, je nach Ihrer Umgebung, könnte es einfacher sein, das Scraping mit einem Javascript-Client durchzuführen.
Da es unmöglich ist, mit Javascript zu arbeiten, kann ich eine andere Lösung vorschlagen:
Google Chrome> Rechts-Taste> Inspect Element> Rechts-Taste> bearbeiten als html> Kopieren> Arbeit mit kopierten HTML
$html = $the_copied_html;
$crawler = new Crawler($html);
$data = $crawler->filter('.your-selector')->each(function (Crawler $node, $i) {
return [
'text' => $node->text()
];
});
//Do whatever you want with the $data
return $data; //type Array
Dies funktioniert nur für einzelne Jobs und nicht für automatisierte Prozesse. In meinem Fall wird es das tun.
Sie möchten sich phantomjs ansehen. Es gibt diese PHP-Implementierung:
http://jonnnnyw.github.io/php-phantomjs/
, wenn Sie brauchen, um es mit PHP natürlich arbeiten.
Sie könnten die Seite lesen und dann den Inhalt an Guzzle senden, um die netten Funktionen zu nutzen, die Ihnen Guzzle bietet (wie die Suche nach Inhalten, etc ...). Das würde auf Ihre Bedürfnisse ab, vielleicht können Sie einfach die dom verwenden, wie folgt aus:
How to get element by class name?
Hier finden Sie einige Arbeitscode.
$content = $this->getHeadlessReponse($url);
$this->crawler->addContent($this->getHeadlessReponse($url));
/**
* Get response using a headless browser (phantom in this case).
*
* @param $url
* URL to fetch headless
*
* @return string
* Response.
*/
public function getHeadlessReponse($url) {
// Fetch with phamtomjs
$phantomClient = PhantomClient::getInstance();
// and feed into the crawler.
$request = $phantomClient->getMessageFactory()->createRequest($url, 'GET');
/**
* @see JonnyW\PhantomJs\Http\Response
**/
$response = $phantomClient->getMessageFactory()->createResponse();
// Send the request
$phantomClient->send($request, $response);
if($response->getStatus() === 200) {
// Dump the requested page content
return $response->getContent();
}
}
Nur Nachteil Phantom verwendet wird, wird es langsamer als verputzen, aber natürlich müssen Sie warten, für alle jene nervtötenden js geladen werden.
Es wäre auch gut zu überprüfen, ob '$ response-> getStatus()' auch gleich 301 ist, falls es eine Umleitung ist. – thisiskelvin