Dieses Paket stellt eine Klasse zum Crawlen von Links auf einer Website bereit. Unter der Haube werden Guzzle-Versprechen verwendet, um mehrere URLs gleichzeitig zu crawlen.
Da der Crawler JavaScript ausführen kann, kann er mit JavaScript gerenderte Websites crawlen. Unter der Haube werden Chrome und Puppeteer verwendet, um diese Funktion zu betreiben.
Wir investieren viele Ressourcen in die Erstellung erstklassiger Open-Source-Pakete. Sie können uns unterstützen, indem Sie eines unserer kostenpflichtigen Produkte kaufen.
Wir freuen uns sehr, dass Sie uns eine Postkarte aus Ihrer Heimatstadt schicken und erwähnen, welches unserer Pakete Sie verwenden. Unsere Adresse finden Sie auf unserer Kontaktseite. Wir veröffentlichen alle erhaltenen Postkarten auf unserer virtuellen Postkartenwand.
Dieses Paket kann über Composer installiert werden:
Komponist benötigt Spatie/Crawler
Der Crawler kann so instanziiert werden
Verwenden Sie SpatieCrawlerCrawler; Crawler::create() ->setCrawlObserver(<Klasse, die SpatieCrawlerCrawlObserversCrawlObserver erweitert>) ->startCrawling($url);
Das an setCrawlObserver
übergebene Argument muss ein Objekt sein, das die abstrakte Klasse SpatieCrawlerCrawlObserversCrawlObserver
erweitert:
Namespace SpatieCrawlerCrawlObservers; GuzzleHttpExceptionRequestException verwenden; PsrHttpMessageResponseInterface verwenden; PsrHttpMessageUriInterface verwenden; abstrakte Klasse CrawlObserver {/* * Wird aufgerufen, wenn der Crawler die URL crawlt. */public function willCrawl(UriInterface $url, ?string $linkText): void{ }/* * Wird aufgerufen, wenn der Crawler die angegebene URL erfolgreich gecrawlt hat. */abstract öffentliche Funktion gecrawlt(UriInterface $url,ResponseInterface $response, ?UriInterface $foundOnUrl = null, ?string $linkText, ): void;/* * Wird aufgerufen, wenn der Crawler beim Crawlen der angegebenen URL ein Problem hatte. */abstract öffentliche Funktion crawlFailed(UriInterface $url,RequestException $requestException, ?UriInterface $foundOnUrl = null, ?string $linkText = null, ): void;/** * Wird aufgerufen, wenn der Crawl beendet ist. */public function doneCrawling(): void{ } }
Sie können mit setCrawlObservers
mehrere Beobachter festlegen:
Crawler::create() ->setCrawlObservers([ <Klasse, die SpatieCrawlerCrawlObserversCrawlObserver erweitert>, <Klasse, die SpatieCrawlerCrawlObserversCrawlObserver erweitert>, ... ]) ->startCrawling($url);
Alternativ können Sie mit addCrawlObserver
mehrere Beobachter einzeln festlegen:
Crawler::create() ->addCrawlObserver(<Klasse, die SpatieCrawlerCrawlObserversCrawlObserver erweitert>) ->addCrawlObserver(<Klasse, die SpatieCrawlerCrawlObserversCrawlObserver erweitert>) ->addCrawlObserver(<Klasse, die SpatieCrawlerCrawlObserversCrawlObserver erweitert>) ->startCrawling($url);
Standardmäßig führt der Crawler kein JavaScript aus. So können Sie die Ausführung von JavaScript aktivieren:
Crawler::create() ->executeJavaScript() ...
Um es zu ermöglichen, den HTML-Text nach der Ausführung des Javascripts abzurufen, hängt dieses Paket von unserem Browsershot-Paket ab. Dieses Paket verwendet Puppeteer unter der Haube. Hier finden Sie einige Hinweise zur Installation auf Ihrem System.
Browsershot erstellt eine fundierte Schätzung darüber, wo seine Abhängigkeiten auf Ihrem System installiert sind. Standardmäßig instanziiert der Crawler eine neue Browsershot-Instanz. Möglicherweise müssen Sie eine benutzerdefinierte erstellte Instanz mithilfe der Methode setBrowsershot(Browsershot $browsershot)
festlegen.
Crawler::create() ->setBrowsershot($browsershot) ->executeJavaScript() ...
Beachten Sie, dass der Crawler auch dann funktioniert, wenn Sie nicht über die für Browsershot erforderlichen Systemabhängigkeiten verfügen. Diese Systemabhängigkeiten sind nur erforderlich, wenn SieexecuteJavaScript executeJavaScript()
aufrufen.
Mit der Funktion setCrawlProfile
können Sie dem Crawler mitteilen, bestimmte URLs nicht zu besuchen. Diese Funktion erwartet ein Objekt, das SpatieCrawlerCrawlProfilesCrawlProfile
erweitert:
/* * Bestimmen Sie, ob die angegebene URL gecrawlt werden soll. */public function ShouldCrawl(UriInterface $url): bool;
Dieses Paket enthält standardmäßig drei CrawlProfiles
:
CrawlAllUrls
: Dieses Profil crawlt alle URLs auf allen Seiten, einschließlich URLs zu einer externen Website.
CrawlInternalUrls
: Dieses Profil crawlt nur die internen URLs auf den Seiten eines Hosts.
CrawlSubdomains
: Dieses Profil crawlt nur die internen URLs und ihre Subdomains auf den Seiten eines Hosts.
Sie können anpassen, wie Links von einer Seite extrahiert werden, indem Sie einen benutzerdefinierten UrlParser
an den Crawler übergeben.
Crawler::create() ->setUrlParserClass(<Klasse, die SpatieCrawlerUrlParsersUrlParser implementiert>::class) ...
Standardmäßig wird der LinkUrlParser
verwendet. Dieser Parser extrahiert alle Links aus dem href
-Attribut a
Tags.
Es gibt auch einen integrierten SitemapUrlParser
, der alle Links aus einer Sitemap extrahiert und crawlt. Es unterstützt Sitemap-Indexdateien.
Crawler::create() ->setUrlParserClass(SitemapUrlParser::class) ...
Standardmäßig respektiert der Crawler Roboterdaten. Es ist möglich, diese Prüfungen wie folgt zu deaktivieren:
Crawler::create() ->ignoreRobots() ...
Robots-Daten können entweder aus einer robots.txt
Datei, Meta-Tags oder Antwortheadern stammen. Weitere Informationen zur Spezifikation finden Sie hier: http://www.robotstxt.org/.
Das Parsen von Roboterdaten erfolgt durch unser Paket spatie/robots-txt.
Standardmäßig lehnt der Crawler alle Links ab, die das Attribut rel="nofollow" enthalten. Es ist möglich, diese Prüfungen wie folgt zu deaktivieren:
Crawler::create() ->acceptNofollowLinks() ...
Um die robots.txt-Regeln für einen benutzerdefinierten Benutzeragenten zu respektieren, können Sie Ihren eigenen benutzerdefinierten Benutzeragenten angeben.
Crawler::create() ->setUserAgent('mein-agent')
Sie können Ihre spezifische Crawl-Regelgruppe für „my-agent“ in robots.txt hinzufügen. In diesem Beispiel wird das Crawlen der gesamten Website für Crawler, die durch „my-agent“ identifiziert werden, nicht zugelassen.
// Crawling für my-agent nicht zulassen Benutzeragent: mein-agent Nicht zulassen: /
Um die Geschwindigkeit des Crawls zu verbessern, crawlt das Paket standardmäßig gleichzeitig 10 URLs. Wenn Sie diese Zahl ändern möchten, können Sie die setConcurrency
-Methode verwenden.
Crawler::create() ->setConcurrency(1) // Jetzt werden alle URLs einzeln gecrawlt
Standardmäßig fährt der Crawler fort, bis er jede Seite gecrawlt hat, die er finden kann. Dieses Verhalten kann zu Problemen führen, wenn Sie in einer Umgebung mit Einschränkungen arbeiten, beispielsweise einer serverlosen Umgebung.
Das Crawl-Verhalten kann mit den folgenden zwei Optionen gesteuert werden:
Gesamt-Crawl-Limit ( setTotalCrawlLimit
): Dieses Limit definiert die maximale Anzahl der zu crawlenden URLs.
Aktuelles Crawl-Limit ( setCurrentCrawlLimit
): Dies definiert, wie viele URLs während des aktuellen Crawls verarbeitet werden.
Schauen wir uns einige Beispiele an, um den Unterschied zwischen diesen beiden Methoden zu verdeutlichen.
Mit der setTotalCrawlLimit
-Methode können Sie die Gesamtzahl der zu crawlenden URLs begrenzen, unabhängig davon, wie oft Sie den Crawler aufrufen.
$queue = <Ihre Auswahl/Implementierung einer Warteschlange>;// Crawlt 5 URLs und endet.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(5) ->startCrawling($url);// Crawlt nicht weiter, wenn das Gesamtlimit erreicht ist.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(5) ->startCrawling($url);
setCurrentCrawlLimit
wird ein Limit dafür festgelegt, wie viele URLs pro Ausführung gecrawlt werden. Dieser Codeabschnitt verarbeitet bei jeder Ausführung 5 Seiten, ohne dass eine Gesamtbeschränkung der zu crawlenden Seiten besteht.
$queue = <Ihre Auswahl/Implementierung einer Warteschlange>;// Crawlt 5 URLs und endet.Crawler::create() ->setCrawlQueue($queue) ->setCurrentCrawlLimit(5) ->startCrawling($url);// Crawlt die nächsten 5 URLs und endet.Crawler::create() ->setCrawlQueue($queue) ->setCurrentCrawlLimit(5) ->startCrawling($url);
Beide Grenzwerte können zur Steuerung des Crawlers kombiniert werden:
$queue = <Ihre Auswahl/Implementierung einer Warteschlange>;// Crawlt 5 URLs und endet.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(10) ->setCurrentCrawlLimit(5) ->startCrawling($url);// Crawlt die nächsten 5 URLs und endet.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(10) ->setCurrentCrawlLimit(5) ->startCrawling($url);// Crawlt nicht weiter, wenn das Gesamtlimit erreicht ist.Crawler::create() ->setCrawlQueue($queue) ->setTotalCrawlLimit(10) ->setCurrentCrawlLimit(5) ->startCrawling($url);
Sie können setCurrentCrawlLimit
verwenden, um lange laufende Crawls zu unterbrechen. Das folgende Beispiel demonstriert einen (vereinfachten) Ansatz. Es besteht aus einer ersten Anfrage und einer beliebigen Anzahl von Folgeanfragen, die den Crawl fortsetzen.
Um mit dem Crawlen über verschiedene Anfragen zu beginnen, müssen Sie eine neue Warteschlange Ihres ausgewählten Warteschlangentreibers erstellen. Beginnen Sie mit der Übergabe der Warteschlangeninstanz an den Crawler. Der Crawler beginnt, die Warteschlange zu füllen, sobald Seiten verarbeitet und neue URLs entdeckt werden. Serialisieren und speichern Sie die Warteschlangenreferenz, nachdem der Crawler fertig ist (unter Verwendung des aktuellen Crawling-Limits).
// Erstellen Sie eine Warteschlange mit Ihrem Warteschlangentreiber.$queue = <Ihre Auswahl/Implementierung einer Warteschlange>;// Crawlen Sie den ersten Satz von URLsCrawler::create() ->setCrawlQueue($queue) ->setCurrentCrawlLimit(10) ->startCrawling($url);// Serialisieren und speichern Sie Ihre Warteschlange$serializedQueue = serialize($queue);
Für alle folgenden Anfragen müssen Sie Ihre ursprüngliche Warteschlange deserialisieren und an den Crawler übergeben:
// Unserialize queue$queue = unserialize($serializedQueue);// Crawlt den nächsten Satz von URLsCrawler::create() ->setCrawlQueue($queue) ->setCurrentCrawlLimit(10) ->startCrawling($url);// Serialisieren und speichern Sie Ihre Warteschlange$serialized_queue = serialize($queue);
Das Verhalten basiert auf den Informationen in der Warteschlange. Nur wenn die gleiche Queue-Instanz übergeben wird, funktioniert das Verhalten wie beschrieben. Wenn eine völlig neue Warteschlange übergeben wird, gelten die Einschränkungen früherer Crawls – selbst für dieselbe Website – nicht.
Ein Beispiel mit weiteren Details finden Sie hier.
Standardmäßig fährt der Crawler fort, bis er jede Seite der angegebenen URL gecrawlt hat. Wenn Sie die Tiefe des Crawlers begrenzen möchten, können Sie die Methode setMaximumDepth
verwenden.
Crawler::create() ->setMaximumDepth(2)
Die meisten HTML-Seiten sind recht klein. Der Crawler könnte jedoch versehentlich große Dateien wie PDFs und MP3s aufspüren. Um den Speicherverbrauch in solchen Fällen gering zu halten, verwendet der Crawler nur Antworten, die kleiner als 2 MB sind. Wenn beim Streamen einer Antwort diese größer als 2 MB wird, stoppt der Crawler das Streamen der Antwort. Es wird von einem leeren Antworttext ausgegangen.
Sie können die maximale Antwortgröße ändern.
// verwenden wir maximal 3 MB.Crawler::create() ->setMaximumResponseSize(1024 * 1024 * 3)
In einigen Fällen kann es zu einer Geschwindigkeitsbegrenzung kommen, wenn Sie zu aggressiv crawlen. Um dies zu umgehen, können Sie die Methode setDelayBetweenRequests()
verwenden, um zwischen jeder Anfrage eine Pause einzufügen. Dieser Wert wird in Millisekunden ausgedrückt.
Crawler::create() ->setDelayBetweenRequests(150) // Nach jeder gecrawlten Seite wartet der Crawler 150 ms
Standardmäßig wird jede gefundene Seite heruntergeladen (bis zu einer Größe von setMaximumResponseSize()
) und auf zusätzliche Links analysiert. Sie können einschränken, welche Inhaltstypen heruntergeladen und analysiert werden sollen, indem Sie setParseableMimeTypes()
mit einem Array zulässiger Typen festlegen.
Crawler::create() ->setParseableMimeTypes(['text/html', 'text/plain'])
Dadurch wird verhindert, dass der Hauptteil von Seiten heruntergeladen wird, die unterschiedliche MIME-Typen haben, wie Binärdateien, Audio/Video usw., in die wahrscheinlich keine Links eingebettet sind. Diese Funktion spart hauptsächlich Bandbreite.
Beim Crawlen einer Website stellt der Crawler die zu crawlenden URLs in eine Warteschlange. Standardmäßig wird diese Warteschlange mithilfe der integrierten ArrayCrawlQueue
im Speicher gespeichert.
Wenn eine Site sehr groß ist, möchten Sie diese Warteschlange möglicherweise an einem anderen Ort speichern, beispielsweise in einer Datenbank. In solchen Fällen können Sie Ihre eigene Crawl-Warteschlange schreiben.
Eine gültige Crawl-Warteschlange ist jede Klasse, die die SpatieCrawlerCrawlQueuesCrawlQueue
-Schnittstelle implementiert. Sie können Ihre benutzerdefinierte Crawl-Warteschlange über die setCrawlQueue
-Methode im Crawler übergeben.
Crawler::create() ->setCrawlQueue(<Implementierung von SpatieCrawlerCrawlQueuesCrawlQueue>)
Hier
ArrayCrawlQueue
RedisCrawlQueue (Paket eines Drittanbieters)
CacheCrawlQueue für Laravel (Paket eines Drittanbieters)
Laravel-Modell als Warteschlange (Beispiel-App eines Drittanbieters)
Standardmäßig legt der Crawler das Basis-URL-Schema auf http
fest, wenn keins vorhanden ist. Sie haben die Möglichkeit, dies mit setDefaultScheme
zu ändern.
Crawler::create() ->setDefaultScheme('https')
Weitere Informationen zu den letzten Änderungen finden Sie im CHANGELOG.
Weitere Informationen finden Sie unter BEITRAGEN.
Installieren Sie zunächst die Puppeteer-Abhängigkeit, sonst schlagen Ihre Tests fehl.
npm install puppeteer
Um die Tests auszuführen, müssen Sie zunächst den enthaltenen knotenbasierten Server in einem separaten Terminalfenster starten.
CD-Tests/Server npm installieren Knoten server.js
Wenn der Server läuft, können Sie mit dem Testen beginnen.
Komponistentest
Wenn Sie einen Sicherheitsfehler gefunden haben, senden Sie bitte eine E-Mail an [email protected], anstatt den Issue-Tracker zu verwenden.
Es steht Ihnen frei, dieses Paket zu verwenden, aber wenn es in Ihre Produktionsumgebung gelangt, würden wir uns sehr freuen, wenn Sie uns eine Postkarte aus Ihrer Heimatstadt schicken und erwähnen, welches unserer Pakete Sie verwenden.
Unsere Adresse lautet: Spatie, Kruikstraat 22, 2018 Antwerpen, Belgien.
Wir veröffentlichen alle erhaltenen Postkarten auf unserer Firmenwebsite.
Freek Van der Herten
Alle Mitwirkenden
Die MIT-Lizenz (MIT). Weitere Informationen finden Sie in der Lizenzdatei.