Heim >Web-Frontend >js-Tutorial >Beispiel einer einfachen Web-Crawling-Funktion, die von Node.js_node.js implementiert wird

Beispiel einer einfachen Web-Crawling-Funktion, die von Node.js_node.js implementiert wird

WBOY
WBOYOriginal
2016-05-16 16:28:491349Durchsuche

Heutzutage ist Webcrawlen eine bekannte Technologie, aber es gibt immer noch viele Komplexitäten. Einfache Webcrawler sind immer noch schwer mit verschiedenen komplexen Technologien wie Ajax-Rotationstraining, XMLHttpRequest, WebSockets, Flash Sockets usw. zurechtzukommen Webseite.

Nehmen wir als Beispiel unsere Grundbedürfnisse beim Hubdoc-Projekt. In diesem Projekt sammeln wir Rechnungsbeträge, Fälligkeitstermine, Kontonummern und vor allem die Websites von Banken, Versorgungsunternehmen und Kreditkartenunternehmen. PDF der aktuellen Rechnungen. Für dieses Projekt begann ich mit einer sehr einfachen Lösung (ohne die teuren kommerziellen Produkte zu verwenden, die wir derzeit evaluieren) – einem einfachen Crawler-Projekt, das ich vor der Verwendung von Perl bei MessageLab/Symantec durchgeführt hatte. Aber die Ergebnisse waren katastrophal. Die Spammer erstellten Websites, die viel einfacher waren als die von Banken und Versorgungsunternehmen.

Wie kann man dieses Problem lösen? Wir begannen hauptsächlich mit der Verwendung der hervorragenden request-Bibliothek, die von Mikea entwickelt wurde. Stellen Sie eine Anfrage im Browser, überprüfen Sie im Netzwerkfenster, welche Anfrageheader gesendet werden, und kopieren Sie diese Anfrageheader dann in den Code. Der Vorgang ist einfach. Es verfolgt lediglich den Prozess von der Anmeldung bis zum Herunterladen der PDF-Datei und simuliert dann alle Anfragen in diesem Prozess. Um den Umgang mit ähnlichen Dingen zu erleichtern und Webentwicklern das rationellere Schreiben von Crawler-Programmen zu ermöglichen, habe ich die Methode zum Abrufen der Ergebnisse aus HTML in jQuery exportiert (unter Verwendung der leichtgewichtigen cheerio-Bibliothek), was ähnliches ermöglicht Aufgaben einfacher und erleichtert auch die Verwendung von CSS-Selektoren zum Auswählen von Elementen auf einer Seite. Der gesamte Prozess ist in ein Framework eingebettet, und dieses Framework kann auch zusätzliche Aufgaben erledigen, z. B. das Abrufen von Zertifikaten aus der Datenbank, das Laden einzelner Roboter und die Kommunikation mit der Benutzeroberfläche über socket.io.

Dies funktioniert für einige Websites, aber es ist nur ein JS-Skript, nicht mein node.js-Code, den diese Unternehmen auf ihren Websites bereitstellen. Sie haben die alten Probleme auf Komplexität geschichtet, was es sehr schwierig macht, herauszufinden, was zu tun ist, um an den Anmeldeinformationspunkt zu gelangen. Ich habe mehrere Tage lang versucht, durch Kombination mit der request()-Bibliothek einige Websites zu erhalten, aber immer noch ohne Erfolg.

Nachdem es fast abgestürzt wäre, habe ich node-phantomjs entdeckt, eine Bibliothek, die es mir ermöglicht, den phantomjs headless Webkit-Browser vom Knoten aus zu steuern (Anmerkung des Übersetzers: Ich habe diese Überlegung nicht eines entsprechenden Substantivs bedeutet „headless“ hier, dass das Rendern der Seite im Hintergrund ohne Anzeigegerät abgeschlossen wird. Dies scheint eine einfache Lösung zu sein, aber es gibt immer noch einige unvermeidbare Probleme mit PhantomJS, die gelöst werden müssen:

1. PhantomJS kann Ihnen nur sagen, ob die Seite geladen wurde, Sie können jedoch nicht feststellen, ob dabei eine Weiterleitung durch JavaScript oder Meta-Tags erfolgt. Vor allem, wenn JavaScript setTimeout() verwendet, um Aufrufe zu verzögern.

2.PhantomJS stellt Ihnen einen pageLoadStarted-Hook zur Verfügung, mit dem Sie die oben genannten Probleme lösen können. Diese Funktion kann jedoch nur verwendet werden, wenn Sie die Anzahl der zu ladenden Seiten bestimmen und diese Anzahl beim Laden jeder Seite verringern. und sorgen Sie für die Behandlung möglicher Zeitüberschreitungen (da dies nicht immer vorkommt), sodass Ihre Rückruffunktion aufgerufen wird, wenn Ihre Nummer auf 0 sinkt. Dieser Ansatz funktioniert, aber es fühlt sich immer ein bisschen wie ein Hack an.

3. PhantomJS erfordert einen vollständig unabhängigen Prozess für jede gecrawlte Seite, da sonst die Cookies zwischen den einzelnen Seiten nicht getrennt werden können. Wenn Sie denselben PhantomJS-Prozess verwenden, wird die Sitzung auf der angemeldeten Seite an eine andere Seite gesendet.

4. Ressourcen können nicht mit PhantomJS heruntergeladen werden – Sie können die Seite nur als PNG oder PDF speichern. Das ist nützlich, bedeutet aber, dass wir auf request() zurückgreifen müssen, um das PDF herunterzuladen.

5. Aus den oben genannten Gründen muss ich einen Weg finden, Cookies aus der Sitzung von PhantomJS an die Sitzungsbibliothek von request() zu verteilen. Verteilen Sie einfach die Zeichenfolge „document.cookie“, analysieren Sie sie und fügen Sie sie in das Cookie-Glas „request()“ ein.

6. Das Einfügen von Variablen in die Browsersitzung ist nicht einfach. Dazu muss ich eine Zeichenfolge erstellen, um eine Javascript-Funktion zu erstellen.

Code kopieren Der Code lautet wie folgt:

Robot.prototype.add_page_data = Funktion (Seite, Name, Daten) {
page.evaluate(
"function () { var " name " = window." name " = " JSON.stringify(data) "}"
);
}

7. Einige Websites sind immer voller Codes wie console.log() und müssen neu definiert und an den gewünschten Ort ausgegeben werden. Um dies zu erreichen, mache ich Folgendes:
Code kopieren Der Code lautet wie folgt:

if (!console.log) {
var iframe = document.createElement("iframe");
​ document.body.appendChild(iframe);
console = window.frames[0].console;
}

8. Einige Websites sind immer voller Codes wie console.log() und müssen neu definiert und an den gewünschten Ort ausgegeben werden. Um dies zu erreichen, mache ich Folgendes:

Code kopieren Der Code lautet wie folgt:

if (!console.log) {
var iframe = document.createElement("iframe");
​ document.body.appendChild(iframe);
console = window.frames[0].console;
}

9. Es ist nicht einfach, dem Browser mitzuteilen, dass ich auf das a-Tag geklickt habe. Um diese Dinge zu vervollständigen, habe ich den folgenden Code hinzugefügt:
Code kopieren Der Code lautet wie folgt:

var clickElement = window.clickElement = function (id){
var a = document.getElementById(id);
var e = document.createEvent("MouseEvents");
e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
a.dispatchEvent(e);
};

10. Ich muss außerdem die maximale Parallelität von Browsersitzungen begrenzen, um sicherzustellen, dass wir den Server nicht in die Luft jagen. Allerdings liegt diese Grenze weit über dem, was teure kommerzielle Lösungen bieten können. (Anmerkung des Übersetzers: Die kommerzielle Lösung weist eine größere Parallelität auf als diese Lösung)

Nachdem die ganze Arbeit erledigt ist, habe ich eine anständige PhantomJS-Anfrage-Crawler-Lösung. Sie müssen sich mit PhantomJS anmelden, bevor Sie zur Anfrage()-Anfrage zurückkehren können. Dabei wird das in PhantomJS gesetzte Cookie verwendet, um die angemeldete Sitzung zu authentifizieren. Dies ist ein großer Gewinn, da wir den Stream von request() verwenden können, um die PDF-Datei herunterzuladen.

Der gesamte Plan besteht darin, es Webentwicklern relativ einfach zu machen, zu verstehen, wie man mit jQuery und CSS-Selektoren Crawler für verschiedene Websites erstellt. Ich habe noch nicht erfolgreich bewiesen, dass diese Idee machbar ist, aber ich glaube, dass dies bald der Fall sein wird .

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn