Speichern von URLs beim Spidering

7

Ich habe einen kleinen Webspider in Python erstellt, mit dem ich URLs sammle. Der Inhalt interessiert mich nicht. Im Moment behalte ich alle besuchten URLs in einem Satz im Speicher, weil ich nicht möchte, dass meine Spinne URLs zweimal besucht. Natürlich ist das eine sehr begrenzte Möglichkeit, dies zu erreichen.

Wie kann ich meine besuchten URLs am besten nachverfolgen?

Soll ich eine Datenbank verwenden?

  • welcher? MySQL, SQLite, PostgreSQL?
  • Wie soll ich die URLs speichern? Als Primärschlüssel versuchen Sie, jede URL vor dem Besuch einzufügen?

Oder sollte ich sie in eine Datei schreiben?

  • eine Datei?
  • mehrere Dateien? Wie soll ich die Dateistruktur gestalten?

Ich bin mir sicher, dass es Bücher und viele Artikel zu diesem oder ähnlichen Themen gibt. Können Sie mir einen Rat geben, was ich lesen sollte?

    
user313743 11.04.2010, 02:19
quelle

6 Antworten

7

Dies scheinen die wichtigsten Aspekte für mich zu sein:

  1. Sie können die URLs nicht im Speicher behalten, da der RAM-Speicher zu hoch wird
  2. Sie benötigen schnelle Existenznachfragen mindestens O (logn)
  3. Sie brauchen schnelle Einfügungen

Es gibt viele Möglichkeiten, dies zu tun, und es hängt davon ab, wie groß Ihre Datenbank wird. Ich denke, dass eine SQL-Datenbank ein gutes Modell für Ihr Problem zur Verfügung stellen kann.

Wahrscheinlich brauchen Sie nur eine SQLite-Datenbank. In der Regel ist das Suchen nach Zeichenfolgen für die Existenzprüfung ein langsamer Vorgang. Um dies zu beschleunigen, können Sie einen CRC-Hash der URL erstellen und sowohl den CRC als auch die URL in Ihrer Datenbank speichern. Sie hätten einen Index für dieses CRC-Feld.

  • Beim Einfügen: Sie fügen die URL und den Hash
  • ein
  • Wenn Sie eine Existenzsuche durchführen möchten: Sie nehmen den CRC der möglicherweise neuen URL und prüfen, ob er sich bereits in Ihrer Datenbank befindet.

Es besteht natürlich eine Kollisionswahrscheinlichkeit bei den URL-Hashes, aber wenn 100% Spanning für Sie nicht wichtig ist, können Sie bei einer Kollision den Treffer ziehen, wenn Sie keine URL in Ihrer Datenbank haben.

Sie können Kollisionen auch auf viele Arten reduzieren. Zum Beispiel können Sie die Größe Ihrer CRC (CRC8 statt CRC4) erhöhen und einen Hashing-Algorithmus mit einer größeren Größe verwenden. Oder verwenden Sie CRC sowie URL-Länge.

    
Brian R. Bondy 11.04.2010, 02:21
quelle
9

Ich habe viele Spinnen geschrieben. Ein größeres Problem als der Speichermangel ist für mich die Möglichkeit, alle URLs zu verlieren, die Sie bereits gespiegelt haben, wenn der Code oder der Computer abstürzt oder Sie entscheiden, dass Sie den Code optimieren müssen. Wenn dir der Arbeitsspeicher ausgeht, werden die meisten Maschinen und Betriebssysteme in den heutigen Tagen angezeigt, so dass du langsamer wirst, aber immer noch funktioniert. Das erneute Erstellen einer Reihe von URLs, die über Stunden und Stunden Laufzeit gesammelt wurden, weil sie nicht mehr verfügbar sind, kann die Produktivität erheblich beeinträchtigen.

Das Speichern von Informationen im RAM, die Sie NICHT verlieren möchten, ist schlecht. Offensichtlich ist eine Datenbank der beste Weg zu diesem Zeitpunkt, da Sie schnellen wahlfreien Zugriff benötigen, um zu sehen, ob Sie bereits eine URL gefunden haben. Natürlich sind In-Memory-Lookups schneller, aber der Kompromiss, herauszufinden, welche URLs im Speicher bleiben, erhöht den Overhead. Anstatt Code zu schreiben, um herauszufinden, welche URLs ich brauche / nicht brauche, behalte ich sie in der Datenbank und konzentriere mich darauf, meinen Code sauber und wartbar zu machen und meine SQL-Abfragen und -Schemas sinnvoll zu machen. Machen Sie Ihr URL-Feld zu einem eindeutigen Index und der DBM kann sie in kürzester Zeit finden, während redundante Links automatisch vermieden werden.

Ihre Verbindung mit dem Internet und den Websites, auf die Sie zugreifen, ist wahrscheinlich wesentlich langsamer als die Verbindung mit einer Datenbank auf einem Computer in Ihrem internen Netzwerk. Eine SQLite-Datenbank auf dem gleichen Rechner könnte die schnellste sein, obwohl der DBM selbst nicht so ausgefeilt ist wie Postgres, was mein Favorit ist. Ich fand, dass die Datenbank auf eine andere Maschine auf dem gleichen Switch wie meine Spidering-Maschine gesetzt wird, um extrem schnell zu sein; Wenn man eine Maschine mit dem Spidering, Parsing und dann mit der Datenbank liest / schreibt, ist das ziemlich intensiv. Wenn Sie also eine alte Box haben, werfen Sie Linux auf, installieren Sie Postgres und gehen Sie in die Stadt. Werfen Sie etwas mehr RAM in die Box, wenn Sie mehr Geschwindigkeit benötigen. Diese separate Box für die Datenbanknutzung kann sehr schön sein.

    
the Tin Man 11.04.2010 03:04
quelle
4

Es hängt vom Ausmaß des Spiderings ab, das Sie machen werden, und von der Art der Maschine, auf der Sie es tun. Angenommen, eine typische URL ist eine Zeichenfolge von 60 Bytes oder so, ein In-Memory-Set wird etwas mehr als 100 Bytes pro URL benötigen (Sets und Dicts in Python dürfen niemals aus Geschwindigkeitsgründen über 60% voll werden). Wenn Sie eine 64-Bit-Maschine (und eine Python-Distribution) mit ungefähr 16 GB RAM zur Verfügung haben, könnten Sie sicherlich mehr als 10 GB für das fragliche Set aufwenden, so dass Sie problemlos rund 100 Millionen URLs spinnen können; Wenn Sie jedoch eine 32-Bit-Maschine mit 3 GB RAM haben, können Sie dem entscheidenden Satz natürlich nicht viel mehr als einen GB widmen und Sie auf etwa 10 Millionen URLs beschränken. Sqlite würde ungefähr in der gleichen Größenordnung helfen, wo ein 32-Bit-Rechner es nicht schaffen würde, aber ein großzügig ausgestatteter 64-Bit-Rechner könnte - sagen wir 100 oder 200 Millionen URLs.

Darüber hinaus würde ich PostgreSQL empfehlen, was auch den Vorteil hat, dass es auf einem anderen Rechner läuft (auf einem schnellen LAN) und im Prinzip keine Probleme hat, so dass Sie Ihre Hauptmaschine dem Spidering widmen können. Ich denke, dass MySQL & amp; c auch dafür OK sein würde, aber ich liebe PostgreSQL-Standard-Compliance und Robustheit ;-). Dies würde sagen, ein paar Milliarden URLs ohne Probleme (nur eine schnelle Festplatte oder besser eine RAID-Anordnung und so viel RAM, wie Sie sich leisten können, um Dinge zu beschleunigen, natürlich).

Wenn Sie versuchen, Speicher / Speicher mit einem Hash mit fester Länge anstelle von URLs zu speichern, die sehr lang sein können, ist in Ordnung, wenn Sie gelegentlich falsch positive Ergebnisse erhalten, die Sie vom Crawlen abhalten Was ist eigentlich eine neue URL? Solche "Kollisionen" müssen nicht sehr wahrscheinlich sein: Selbst wenn Sie nur 8 Bytes für den Hashwert verwenden, sollten Sie nur ein beträchtliches Kollisionsrisiko haben, wenn Sie Milliarden von URLs betrachten (die "Quadratwurzelheuristik" dafür) bekanntes Problem).

Mit 8-Byte-Strings zur Darstellung der URLs sollte die In-Memory-Set-Architektur problemlos eine Milliarde URLs oder mehr auf einem gut ausgestatteten Computer unterstützen, wie oben beschrieben.

Also, ungefähr wie viele URLs willst du spinnen und wie viel RAM kannst du schonen? -)

    
Alex Martelli 11.04.2010 02:34
quelle
2

Speichern Sie nur URLs? Sie sollten sich mongoDB ansehen. Es ist eine NoSQL-Datenbank, die ziemlich einfach zu implementieren ist.

Ссылка

Es hat auch Python-Bindungen:

Ссылка

    
user297250 11.04.2010 02:30
quelle
1

Da es wahrscheinlich ist, dass Sie ähnliche URLs zu ähnlichen Zeiten sehen werden (zB während Sie eine Website anzeigen, sehen Sie viele Links zur Hauptseite der Website). Ich würde Ihnen empfehlen, die URLs in einem Wörterbuch zu speichern bis Ihr Gedächtnis eingeschränkt wird (schreiben Sie einfach eine vernünftige Zahl wie 10M URLs oder ähnliches) und leeren Sie das Wörterbuch dann in eine CDB-Datenbank Datei , wenn sie zu groß wird.

Auf diese Weise wird der Großteil Ihrer URL-Prüfungen im Speicher (der schnell ist) gespeichert, während diejenigen, die nicht im Speicher sind, nur 1-2 Lesevorgänge von der Festplatte benötigen, um zu überprüfen, dass Sie sie besucht haben / p>     

jemfinch 11.04.2010 02:33
quelle
0

Betrachten Sie Beizen vorläufig: Einfacher strukturierter Speicher.

Die Laufleistung wird natürlich variieren, weil Sie, wie die anderen Responder sagen, Ihren RAM schnell erschöpfen.

    
colgur 11.04.2010 20:24
quelle