Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1739 connectés 

  FORUM HardWare.fr
  Programmation
  Python

  urllib2 et threading

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

urllib2 et threading

n°1863314
pouchat
Posté le 18-03-2009 à 20:12:07  profilanswer
 

Bonjour,
 
j'ai quelques problèmes à comprendre le module threading et les quelques bouts de codes trouvés ne m'en disent pas plus.
Voici mon code simple de départ (il recupere des pages html et envoi un mail si tout est ok):  
 

Code :
  1. #!/usr/bin/env python2.6
  2. # -*- coding: utf-8 -*-
  3. import thread
  4. import urllib2
  5. class robot:
  6.    
  7.     def __init__(self, url):
  8.         self.__url = url
  9.        
  10.        
  11.     def queue(self):
  12.         for page in self.__url:
  13.             html = self.execute(page)
  14.             if html:
  15.                 self.sendmail("le contenu est ok" )
  16.             else:
  17.                 print "erreur sur la page {0}".format(page)
  18.        
  19.        
  20.     def execute(self, url):
  21.         """
  22.         Recupere le contenu html...
  23.         """
  24.         return urllib2.urlopen(url).read()
  25.        
  26.    
  27.     def sendmail(self, message):
  28.         """
  29.         envoi un mail...
  30.         """
  31.         pass
  32.    
  33. if __name__ == '__main__':
  34.    
  35.     url =["http://google.com", "http://www.afpy.org"]
  36.     recupere = robot(url)
  37.     recupere.queue()


Il fonctionne mais va poser des problèmes de vitesse (en fonction du nombre de pages, ou certaines pages qui vont bloquer:timeout...). Bref j'aimerais paralleliser la fonction "execute" donc utiliser le module threading.
 
Le soucis est que j'ai besoin de récupérer le résultats de cette fonction pour générer des tests/messages et je ne vois pas comment faire...
 
merci à ceux qui pourraient m'éclairer


Message édité par pouchat le 18-03-2009 à 20:13:31
mood
Publicité
Posté le 18-03-2009 à 20:12:07  profilanswer
 

n°1863358
masklinn
í dag viðrar vel til loftárása
Posté le 18-03-2009 à 23:03:18  profilanswer
 

Une queue (Queue.Queue) avec les URLs pour l'entrée, une queue pour les sorties.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1863564
pouchat
Posté le 19-03-2009 à 14:40:12  profilanswer
 

j'ai utilisé le module multiprocessing apparement plus performant pour ce que j'ai à faire. J'ai modifié la fonction queue() :
 

Code :
  1. def queue(self):
  2.         time_start = datetime.datetime.now()
  3.         processes =[code]
  4.         for page in self.__url:
  5.             p = Process(target=self.execute, args=(page,))
  6.             p.start()
  7.             processes.append(p)
  8.            
  9.         for p in processes:
  10.             p.join()
  11.        
  12.         #for page in html:
  13.         #    if page:
  14.         #        self.sendmail("le contenu est ok" )
  15.         #    else:
  16.         #        print "erreur sur la page {0}"
  17.        
  18.         time_end = datetime.datetime.now()
  19.         print "execute in {0}sec".format(time_end - time_start)


 
Ca fonctionne mais quelques interrogations :  
- un processus ne retourne "rien". Ca veut dire ma fonction execute qui retourne du code html, je ne pourrais pas le récupérer. A moi, de me débrouiller pour intégrer le test sur le code html directement dans la fonction execute() ?
- si je ne fais pas la boucle avec le p.join(), il arrive parfois que la fonction queue() m'affiche la durée (print "..." ) alors que tous les processus ne sont pas terminés. Ca veut dire que join() assure que tous les process soient terminés ? (je pige pas la doc qui parle de "Block the calling thread" ).
 
 

n°1864220
pouchat
Posté le 20-03-2009 à 21:36:48  profilanswer
 

tu aurais des exemple assez clair avec queue.queue. C'est encore ce que je reproche à python, une bonne doc mais qui manque d'exemples clairs et fonctionnels.
 
merci

n°1864221
Taz
bisounours-codeur
Posté le 20-03-2009 à 21:41:22  profilanswer
 

Mouais, Process c'est peut-être un peur lourd par rapport à threading pour un truc IO-bound

n°1864224
masklinn
í dag viðrar vel til loftárása
Posté le 20-03-2009 à 21:49:21  profilanswer
 

pouchat a écrit :

tu aurais des exemple assez clair avec queue.queue. C'est encore ce que je reproche à python, une bonne doc mais qui manque d'exemples clairs et fonctionnels.

 

merci


Il y en a dans la doc de threading. Mais pour multiprocessing, il faut utiliser multiprocessing.Queue (qui a sensiblement la même interface que Queue.Queue) ou multiprocessing.Pipe (qui n'a pas d'équivalent)

Taz a écrit :

Mouais, Process c'est peut-être un peur lourd par rapport à threading pour un truc IO-bound


:D


Message édité par masklinn le 20-03-2009 à 21:51:14

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1864225
Taz
bisounours-codeur
Posté le 20-03-2009 à 21:51:05  profilanswer
 

Lis la doc du module multiprocessing, t'as tout d'expliquer sur comment échanger des données.
 
Sinon threading + Queue, c'est vraiment simple.

n°1864246
pouchat
Posté le 20-03-2009 à 23:01:04  profilanswer
 

le module threading pas d'exemple même si les descriptions des méthodes sont claires. Pour le multithreading, les 10 premiers bout de codes ne font tourner qu'un seul process à la fois. Je pige pas l'intêret alors que ce module est justement fait pour plusieurs process en même temps. Les exemples suivants font intervenir le manager et la je laisse tomber.
 
J'ai tout de même trouvé qqch de vraiment exploitable à la fin de la doc que queue.queue. Le nouveau code suivant est donc fonctionnel :  
 

Code :
  1. from threading import Thread
  2. from Queue import Queue
  3. def file_dattente(self):
  4.         time_start = datetime.datetime.now()
  5.         num_worker_threads = 2
  6.  
  7.         def worker():
  8.             while True:
  9.                 url = q.get()
  10.                 self.execute(url)
  11.                 q.task_done()
  12.         q = Queue()
  13.         for i in range(num_worker_threads):
  14.              t = Thread(target=worker)
  15.              t.setDaemon(True)
  16.              t.start()
  17.         # ce qui va me lancer le truc
  18.         for page in self.__url:
  19.             q.put(page)
  20.         q.join()    # block until all tasks are done


 
Je m'accroche à sa, donc je résume :  
 
- le 2ème bloc, (q= Queue()) me crée 2 threads dont la fonction cible est worker.
- q.put(), ajoute toutes mes url à la file d'attente
- q.join() stop l'appli jusqu'à ce que chacune des 2 threads ait terminé de faire tourner la fonction worker avec mes url (que la file d'attente soit vide en fait)
 
questions subsidiaires :  
- qu'est ce qui rattache Queue à Thread ? je veux dire c'est donc implicite qu'un q.join() soit rattaché à des Threads ?
- dans cette exemple il n'y a pas de retour réel de variable sur Thread. Je dois faire le test de mon code html à l'intérieur de worker ?
- le setDaemon a t'il un vrai intérêt, performances... ?
- est-ce que cette méthode (threading. + queue) est la plus rapide ?
- est ce que c'est une bonne façon de s'y prendre (the python way) ? Pour rappel, le but est de recupérer du html sur des pages distantes, et si le html est ok j'envois le contenu du html à une fonction.

Message cité 1 fois
Message édité par pouchat le 20-03-2009 à 23:03:56
n°1864248
masklinn
í dag viðrar vel til loftárása
Posté le 20-03-2009 à 23:20:51  profilanswer
 

pouchat a écrit :

- qu'est ce qui rattache Queue à Thread ? je veux dire c'est donc implicite qu'un q.join() soit rattaché à des Threads ?


Aucun rapport avec les threads, la réponse est dans la doc suffit de lire.

 
pouchat a écrit :

- dans cette exemple il n'y a pas de retour réel de variable sur Thread. Je dois faire le test de mon code html à l'intérieur de worker ?


wat?

pouchat a écrit :

- le setDaemon a t'il un vrai intérêt, performances... ?


jamais tu lis la doc?

pouchat a écrit :

- est-ce que cette méthode (threading. + queue) est la plus rapide ?


1. Par rapport à quoi
2. Who cares? Ton bottleneck c'est la récupération des pages web de toute façon [:petrus75]

pouchat a écrit :

- est ce que c'est une bonne façon de s'y prendre (the python way) ? Pour rappel, le but est de recupérer du html sur des pages distantes, et si le html est ok j'envois le contenu du html à une fonction.


C'est une façon qui fonctionne en Python si tu veux fetcher plusieurs URLs en parallèle.

Message cité 1 fois
Message édité par masklinn le 20-03-2009 à 23:23:00

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1864271
pouchat
Posté le 21-03-2009 à 00:58:59  profilanswer
 

masklinn a écrit :


Aucun rapport avec les threads, la réponse est dans la doc suffit de lire.


En fait je me suis mal expliqué. C'est simplement qu'à travers l'objet Queue() on va agir du moins "gérer" les Threads.
 
 

masklinn a écrit :


1. Par rapport à quoi
2. Who cares? Ton bottleneck c'est la récupération des pages web de toute façon [:petrus75]


Disons qu'a priori niveau vitesse d'execution, seuls les modules threading et multiprocessing peuvent faire qqch. Donc une comparaison entre les 2. Mais comme tu as que les thread sont plus léger je reste sur ça.
 
 

masklinn a écrit :


C'est une façon qui fonctionne en Python si tu veux fetcher plusieurs URLs en parallèle.


Le resultat n'a pas d'importance, c'est juste pour avoir une première approche du module threading en gardant un script de base simple.
 
Et il me reste encore quelques problèmes à régler pour vraiment avoir un script qui marche :  
 - les exceptions en cas de problème dans ma fonction execute() ou worker()
 - si j'y ajoute une insertion dans la base, de temps en temps mon script se bloque ? sûrement un problème d'accès entre les threads...


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Python

  urllib2 et threading

 

Sujets relatifs
Threading et exception?[Python] Requete HTTP sans proxy avec urllib2
Tkinter et threadingproblème de connexion HTTP J2ME avec Threading
SWT et Mult-Threading[MinGW/Boost.Thread] Segfault multi-threading
[C++/SDL] pb de threading[C++] Threading --> PB de creation de thread (MFC)
[MS-DOS] Multi-threadingmulti-threading en Visual C++
Plus de sujets relatifs à : urllib2 et threading


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR