Heute ist Web Crawling eine bekannte Technologie, aber es gibt immer noch viele Komplexitäten. Einfache Webcrawler sind immer noch schwierig, mit modernen Websites zu konkurrieren, die von verschiedenen komplexen Technologien wie AJAX -Training, XMLHTTPrequest, Websockets, Flash Sockets usw. entwickelt wurden.
Nehmen wir unsere Grundbedürfnisse für das Hubdoc -Projekt als Beispiel als Beispiel an, in dem wir den Rechnungsbetrag, das Ablaufdatum, die Kontonummer und vor allem: PDFs der jüngsten Rechnungen von den Websites von Banken, Versorgungsunternehmen und Kreditkartenunternehmen kriechen. Für dieses Projekt habe ich mit einer sehr einfachen Lösung begonnen (ohne das teure kommerzielle Produkt, das wir vorerst bewerten) - ein einfaches Crawler -Projekt, das ich früher mit Perl in Messagelab/Symantec gemacht habe. Aber die Ergebnisse lief nicht gut und die Spammer machten eine viel einfachere Website als die von Banken und Versorgungsunternehmen.
Wie kann man dieses Problem lösen? Wir beginnen hauptsächlich mit der hervorragenden Anfrage -Bibliothek, die mit MIKEA entwickelt wurde. Stellen Sie eine Anfrage im Browser und überprüfen Sie, welche Anforderungsheader im Netzwerkfenster verschickt wurden, und kopieren Sie diese Anforderungsheader in den Code. Dieser Prozess ist sehr einfach. Es soll nur alle Anfragen vom Anmeldung zum Herunterladen der PDF -Datei verfolgen und dann alle Anforderungen aus diesem Vorgang simulieren. Um es einfacher zu machen, ähnliche Dinge zu behandeln und Webentwickler beim Schreiben von Crawler -Programmen rationaler zu machen, habe ich die Ergebnisse von HTML in JQuery (mit der Leichtgewichts -Cheatio -Bibliothek) exportiert, die ähnliche Arbeiten einfacher machte und es einfacher machte, den CSS -Selektor zu verwenden, um Elemente auf einer Seite auszuwählen. Der gesamte Prozess ist in ein Framework eingebunden, das auch zusätzliche Arbeiten ausführen kann, z. B. Zertifikate 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 handelt sich nur um ein JS -Skript, nicht um meinen Node.js -Code, der von diesen Unternehmen auf ihrer Website platziert wird. Sie können die übrig gebliebenen Probleme aufweisen, um die Komplexität anzugehen, und es für Sie sehr schwierig ist, herauszufinden, was zu tun ist, um den Anmeldeinformationspunkt zu erhalten. Für einige Websites habe ich versucht, es für ein paar Tage mit der Request () -Bibliothek zu kombinieren, aber es war immer noch vergeblich.
Nach fast Abstürzen entdeckte ich Knotenphantomjs, eine Bibliothek, mit der ich den Kopflosen-Webkit-Browser von Phantomjs vom Knoten steuern kann (Übersetzer Anmerkung: Ich habe kein entsprechendes Substantiv erwartet. Dies scheint eine einfache Lösung zu sein, aber es gibt einige Probleme, die Phantomjs nicht vermeiden können:
1.Phantomjs kann Ihnen nur sagen, ob die Seite geladen wurde. Sie können jedoch nicht feststellen, ob in diesem Prozess um Umleitung (Weiterleitungen) über JavaScript- oder Meta -Tags implementiert sind. Insbesondere wenn JavaScript setTimeout () verwendet, um Anrufe zu verzögern.
2.Phantomjs bietet Ihnen einen pageloadStarted -Haken, mit dem Sie die oben genannten Probleme bewältigen können. Diese Funktion kann diese Zahl jedoch nur reduzieren, wenn Sie die Anzahl der Seiten der Seiten ermitteln, und die Verarbeitung für mögliche Zeitüberschreitungen bereitstellen (da dies nicht immer passiert), so dass Ihre Anzahl auf 0 reduziert wird, kann Ihre Rückruffunktion aufgerufen werden. Diese Methode kann funktionieren, aber sie fühlen sich immer ein bisschen wie ein Hacker.
3.Phantomjs erfordert einen vollständigen und unabhängigen Prozess für jede Seite, da dies nicht der Fall ist, wenn dies nicht der Fall ist, es unmöglich ist, Cookies zwischen jeder Seite zu trennen. Wenn Sie denselben Phantomjs -Prozess verwenden, wird die Sitzung auf der Seite, die angemeldet wurde, an eine andere Seite gesendet.
V. Dies ist nützlich, aber wir müssen zurückgreifen, um die PDF herunterzuladen.
5. Aus den oben genannten Gründen muss ich einen Weg finden, Cookies von Phantomjs Sitzung auf die Sitzungsbibliothek von Request () zu verteilen. Verteilen Sie einfach das Dokument.cookie -Zeichenfolge, analysieren Sie es und geben Sie es in das Cookie -Glas von Request () ein.
6. Es ist nicht einfach, Variablen in die Browser -Sitzung zu injizieren. Dazu muss ich eine Zeichenfolge erstellen, um eine JavaScript -Funktion zu erstellen.
Die Codekopie lautet wie folgt:
Robot.Prototype.add_page_data = Funktion (Seite, Name, Daten) {
Page.Valuate (
"function () {var" + name + "= Fenster." + name + "=" + json.stringify (Daten) + "}"
);
}
7. Einige Websites sind immer mit Code wie Console.log () gefüllt und müssen neu definiert und an den gewünschten Ort ausgegeben werden. Um dies zu erreichen, habe ich das getan:
Die Codekopie 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 mit Code wie Console.log () gefüllt und müssen neu definiert und an den gewünschten Ort ausgegeben werden. Um dies zu erreichen, habe ich das getan:
Die Codekopie 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 zu sagen, dass ich auf das A -Tag geklickt habe. Um diese Dinge zu erreichen, habe ich den folgenden Code hinzugefügt:
Die Codekopie lautet wie folgt:
var clickElement = window.clickelement = function (id) {
var a = document.getElementById (id);
var e = document.createEvent ("Mouseevents");
E.InitMouseEvent ("Click", True, True, Fenster, 0, 0, 0, 0, falsch, falsch, falsch, falsch, 0, null);
a.DispatchEvent (e);
};
10. Ich muss auch die maximale Parallelität der Browser -Sitzung einschränken, um sicherzustellen, dass wir den Server nicht explodieren. Trotzdem ist diese Einschränkung viel höher als die teuren kommerziellen Lösungen. (Anmerkung des Übersetzers: Das heißt, die Parallelität einer kommerziellen Lösung ist größer als die dieser Lösung)
Nach all der Arbeit habe ich eine relativ anständige Crawler -Lösung für Phantomjs + Anfrage. Sie müssen sich mit Phantomjs anmelden, bevor Sie zur Anfrage Request () zurückkehren können. In Phantomjs werden Cookies verwendet, um die angemeldete Sitzung zu überprüfen. Dies ist ein großer Sieg, da wir den Stream von Request () verwenden können, um die PDF -Datei herunterzuladen.
Der gesamte Plan besteht darin, dass Webentwickler es relativ einfach macht, zu verstehen, wie JQuery- und CSS -Selektoren verwendet werden, um Crawler für verschiedene Websites zu erstellen. Ich habe nicht erfolgreich bewiesen, dass diese Idee machbar ist, aber ich glaube, dass es bald passieren wird.