7
votes

Stocker des URL pendant que des spidées

J'ai créé une petite araignée Web à Python que j'utilise pour collecter des URL. Je ne suis pas intéressé par le contenu. En ce moment, je garde toutes les URL visitées dans un ensemble en mémoire, car je ne veux pas que mon araignée visite des URL deux fois. Bien sûr, c'est un moyen très limité d'accomplir cela.

Alors, quelle est la meilleure façon de garder une trace de mes URL visitées?

devrais-je utiliser une base de données?

  • lequel? Mysql, sqlite, postgregesql?
  • Comment dois-je enregistrer les URL? En tant que clé primaire, essayant d'insérer chaque URL avant de le visiter?

    ou devrais-je les écrire dans un fichier?

    • un fichier?
    • plusieurs fichiers? Comment dois-je concevoir la structure de fichiers?

      Je suis sûr qu'il y a des livres et beaucoup de papiers sur ce sujet ou sur des sujets similaires. Pouvez-vous me donner des conseils ce que je devrais lire?


1 commentaires

C'est un problème assez lourd difficile, dépend de la difficulté de savoir que vous souhaitez que votre solution :) Le plus gros problème que vous rencontrez est des sites qui mettent des biscuits et des nombres aléatoires dans leurs URL, qui conduit à un espace d'analyse infini pour se faire coincer , à un moment donné, vous devrez commencer à supprimer des doublons en fonction du contenu.


6 Réponses :


7
votes

Celles-ci semblent être les aspects importants pour moi:

  1. Vous ne pouvez pas garder les URL en mémoire, car RAM sera trop élevé
  2. Vous avez besoin de recherches d'existence rapide au moins O (logn)
  3. Vous avez besoin d'insertions rapides

    Il existe de nombreuses façons de le faire et cela dépend de la taille de votre base de données. Je pense qu'une base de données SQL peut fournir un bon modèle pour votre problème.

    Tout ce dont vous avez besoin est une base de données SQLite. Typiquement les recherches de chaîne pour la vérification de l'existence sont une opération lente. Pour accélérer cela, vous pouvez créer un hasch CRC de l'URL et stocker à la fois la CRC et l'URL de votre base de données. Vous auriez un index sur ce champ de CRC.

    • Lorsque vous insérez: vous insérez l'URL et le hachage
    • Lorsque vous souhaitez effectuer une recherche d'existence: vous prenez la CRC de la puissante nouvelle URL et vérifiez s'il est déjà dans votre base de données.

      Il y a bien sûr une chance de collision sur les hauts de l'URL, mais si 100% couvrant n'est pas important pour vous, vous pouvez tirer le coup de ne pas avoir une URL dans votre DB lorsqu'il y a une collision.

      Vous pouvez également réduire les collisions de plusieurs manières. Par exemple, vous pouvez augmenter la taille de votre CRC (CRC8 au lieu de CRC4) et utilisez un algorithme de hachage avec une taille plus grande. Ou utilisez la longueur de la CRC aussi bien que l'URL.


0 commentaires

2
votes

Ne stockez-vous que d'URL? Vous devriez jeter un oeil à mongodb. C'est une base de données NOSQL qui est assez facile à mettre en œuvre.

http://try.mongodb.org/

Il a aussi des liaisons python, aussi:

http://api.mongodb.org/python/1.5 .2% 2b / index.html


0 commentaires

1
votes

Comme il est probable que vous verrez des URL similaires à des moments similaires (par exemple, tandis que SPIDERING A Site Web, vous verrez beaucoup de liens vers la page principale du site Web) Je vous conseillerais de garder les URL dans un dictionnaire Jusqu'à ce que votre mémoire devienne limitée (il suffit de coder un nombre raisonnable comme des URL de 10 m ou similaire), puis affleurez le dictionnaire à un fichier de base de données CDB quand il devient trop grand.

De cette façon, la majorité de vos chèques d'URL seront en mémoire (ce qui est rapide), tandis que ceux qui ne sont pas en mémoire ne nécessiteront toujours que 1-2 se lit à partir du disque pour vérifier que vous les avez visités. < / p>


0 commentaires

4
votes

Cela dépend de l'échelle de l'araignée que vous allez faire et du type de machine que vous le faites. Supposons qu'une URL typique est une chaîne de 60 octets ou donc, un ensemble en mémoire prendra un peu plus de 100 octets par URL (des ensembles et des dicts dans Python ne sont jamais autorisés à se développer au-delà de 60% de 60%, pour des raisons de vitesse). Si vous avez une machine de 64 bits (et une distribution de Python) avec environ 16 Go de RAM disponible, vous pouvez sûrement consacrer plus de 10 Go à l'ensemble crucial en question, vous permettant de vous laisser facilement spider environ 100 millions d'URL; Mais à l'autre extrême, si vous avez une machine de 32 bits avec 3 Go de RAM, vous ne pouvez clairement pas consacrer beaucoup plus qu'un GB à l'ensemble crucial, vous limitant à environ 10 millions d'URL. SQLite aiderait autour de la même gamme de dimensions où une machine de 32 bits ne pouvait pas le faire, mais on pouvait généreusement doté de 64 bits - dire 100 ou 200 millions d'URL.

Au-delà de ceux-ci, je recommanderais PostgreSQL, qui présente également l'avantage de pouvoir fonctionner sur une machine différente (sur un réseau local) avec fondamentalement aucun problème, vous permettant de consacrer votre machine principale à spidering. Je suppose que MySQL & C irait bien pour cela aussi, mais j'aime la conformité standard et la robustesse standard postgresql ;-). Cela permettrait, disons quelques milliards d'URL sans problèmes (juste un disque rapide, ou mieux un arrangement de raid, et autant de RAM que possible pour accélérer les choses, bien sûr).

Essayer de sauvegarder la mémoire / le stockage à l'aide d'un hachage de longueur fixe au lieu d'URL qui pourrait être assez long, c'est bien si vous êtes ok avec un faux positif occasionnel qui vous empêchera de ramper Qu'est-ce qui est en réalité une nouvelle URL. Ces «collisions» ne doivent pas nécessairement être du tout probables: même si vous n'utilisez que 8 octets pour le hachage, vous ne devez avoir un risque substantiel de certaines collisions lorsque vous regardez des milliards d'URL (la «Heurtiste de la racine carrée» pour cela. Problème bien connu).

avec des chaînes de 8 octets pour représenter les URL, l'architecture de réglage en mémoire doit facilement prendre en charge un milliard d'URL ou plus sur une machine bien dotée comme ci-dessus décrite.

Donc, à peu près combien d'URL voulez-vous spider et combien de RAM pouvez-vous épargner? -)


0 commentaires

9
votes

J'ai écrit beaucoup d'araignées. Pour moi, un problème plus important que de manquer de mémoire est le potentiel de perdre toutes les URL que vous avez également spidérées si le code ou la machine se bloque ou que vous décidez que vous devez modifier le code. Si vous manquez de RAM, la plupart des machines et des OSES de la RAM ces jours-ci seront de la page afin que vous ralentissez, mais encore fonctionner. Devoir reconstruire un ensemble d'URL réuni sur des heures et des heures de temps d'exécution, car il n'est plus disponible peut être un vrai coup de productivité.

Garder des informations dans la RAM que vous ne voulez pas perdre est mauvais. Évidemment, une base de données est la voie à suivre à ce moment-là car vous avez besoin d'un accès aléatoire rapide pour voir si vous avez déjà trouvé une URL. Bien sûr, les recherches en mémoire sont plus rapides, mais le compromis de déterminer les URL à garder en mémoire ajoute des frais généraux. Plutôt que d'essayer de rédiger un code pour déterminer quelles URL dont j'ai besoin / n'avez pas besoin, je le garde dans la base de données et concentrez-vous sur mon code propre et maintenable et mes requêtes et schémas SQL. Faites votre champ d'URL un index unique et le DBM pourra les trouver en un rien de temps tout en évitant automatiquement les liens redondants.

Votre connexion à Internet et aux sites que vous accédez aura probablement beaucoup plus lentement que votre connexion à une base de données sur une machine sur votre réseau interne. Une base de données SQLite sur la même machine pourrait être la plus rapide, bien que la DBM elle-même n'est pas aussi sophistiquée que Postgres, qui est mon préféré. J'ai constaté que mettre la base de données sur une autre machine sur le même commutateur que ma machine spidering sera extrêmement rapide; Fabriquer une machine à gérer l'araignée, l'analyse, puis la base de données se lit / écrit est assez intensif, donc si vous avez une vieille boîte, installez Linux, installez Postgres et allez en ville. Jetez une mémoire supplémentaire dans la boîte si vous avez besoin de plus de vitesse. Avoir cette boîte séparée pour une utilisation de la base de données peut être très agréable.


0 commentaires

0
votes

Considérez Pickling pour l'instant: stockage structuré simple.

Le kilométrage variera bien sûr car, comme l'ont dit les autres intervenants, vous épuiserez rapidement votre RAM.


0 commentaires