2009-11-23 6 views
3

Je travaille sur une araignée multi-processus en Python. Il devrait commencer à gratter une page pour les liens et travailler à partir de là. Plus précisément, la page de niveau supérieur contient une liste de catégories, les événements de pages de second niveau dans ces catégories et les pages finales de participants aux événements de troisième niveau. Je ne peux pas prédire combien de catégories, d'événements ou de participants il y aura. Je suis un peu perplexe quant à la meilleure façon de concevoir une telle araignée, et en particulier, comment savoir quand il est fini d'explorer (il devrait continuer jusqu'à ce qu'il ait découvert et récupéré chaque page pertinente) .Conception d'une araignée multi-processus en Python

Idéalement, la première éraflure serait synchrone, et tout le reste async pour maximiser l'analyse parallèle et l'ajout à la base de données, mais je suis coincé sur la façon de comprendre quand l'exploration est terminée.

Comment suggéreriez-vous que je structure l'araignée, en termes de processus parallèles et en particulier le problème ci-dessus?

Répondre

1

Je suppose que vous mettez des articles à visiter dans un queue, épuisant la file d'attente avec les travailleurs, et les travailleurs trouvent de nouveaux éléments à visiter et les ajouter à la file d'attente.

Il est terminé lorsque tous les travailleurs sont inactifs et que la file d'attente des éléments à visiter est vide.

Lorsque les travailleurs utilisent la méthode task_done() de la file d'attente, le thread principal peut join() bloquer la file d'attente jusqu'à ce qu'elle soit vide.

+0

Hmm. Comment saurais-je si la file d'attente est vide parce que tout est fini, ou parce qu'il y a, par exemple, moins de catégories que les processus de travail, ce qui vide la file d'attente même si elle est loin d'être terminée? – wbg

+0

Désolé, j'ai posté trop tôt. J'ai réfléchi plus sur ce que vous avez dit, et multiprocessing.JoinableQueue.task_done() et .join() sont exactement ce que je cherche. Je dois juste être sûr d'ajouter de nouvelles tâches à la file d'attente avant d'appeler task_done(). Merci! – wbg

2

Vous pouvez examiner Scrapy, un Web-scraper asynchrone (basé sur Twisted). Il semble que pour votre tâche, la description XPath pour l'araignée serait assez facile à définir!

Bonne chance!

(Si vous voulez vraiment le faire vous-même, peut-être envisager d'avoir petite sqlite db qui permet de suivre si chaque page a été touchée ou non ... ou si sa taille est raisonnable, faites-le en mémoire ... en général pourrait être votre ami pour frapper.)

+0

J'ai déjà les modules et les classes de composants (parseurs, db etc.), mais je suis coincé sur la façon de les assembler. Si je garde une trace des pages que j'ai touchées, comment puis-je savoir quand j'ai fini la/last/page? – wbg

+0

J'imagine (dans un système synchrone), vous gardez une file d'attente ou une pile (en ajoutant des pages quand vous regardez une page de groupe, ou autre) et quand il arrive à vider, vous avez terminé. –

+0

Synchrone est facile. Je pense que je l'ai léché, merci. Je n'avais pas bien compris task_done() correctement. – wbg