2010-06-26 4 views
1

Je suis en train d'écrire un script python pour lire une liste de domaines, savoir quelle note donne le service Siteadvisor de Mcafee, puis afficher le domaine et le résultat dans un fichier CSV. J'ai basé mon script sur this previous answer. Il utilise l'urllib pour gratter la page de Siteadvisor pour le domaine en question (pas la meilleure méthode, je sais, mais Siteadvisor ne fournit aucune alternative). Malheureusement, il ne parvient pas à produire quoi que ce soit - je reçois toujours cette erreur:Comment puis-je corriger ce script Python multithread?

Traceback (most recent call last): 
    File "multi.py", line 55, in <module> 
    main() 
    File "multi.py", line 44, in main 
    resolver_thread.start() 
    File "/usr/lib/python2.6/threading.py", line 474, in start 
    _start_new_thread(self.__bootstrap,()) 
thread.error: can't start new thread 

Voici mon script:

import threading 
import urllib 

class Resolver(threading.Thread): 
    def __init__(self, address, result_dict): 
     threading.Thread.__init__(self) 
     self.address = address 
     self.result_dict = result_dict 

    def run(self): 
     try: 
      content = urllib.urlopen("http://www.siteadvisor.com/sites/" + self.address).read(12000) 
      search1 = content.find("didn't find any significant problems.") 
      search2 = content.find('yellow') 
      search3 = content.find('web reputation analysis found potential security') 
      search4 = content.find("don't have the results yet.") 

      if search1 != -1: 
       result = "safe" 
      elif search2 != -1: 
       result = "caution" 
      elif search3 != -1: 
       result = "warning" 
      elif search4 != -1: 
       result = "unknown" 
      else: 
       result = "" 

      self.result_dict[self.address] = result 

     except: 
      pass 


def main(): 
    infile = open("domainslist", "r") 
    intext = infile.readlines() 
    threads = [] 
    results = {} 
    for address in [address.strip() for address in intext if address.strip()]: 
     resolver_thread = Resolver(address, results) 
     threads.append(resolver_thread) 
     resolver_thread.start() 

    for thread in threads: 
     thread.join() 

    outfile = open('final.csv', 'w') 
    outfile.write("\n".join("%s,%s" % (address, ip) for address, ip in results.iteritems())) 
    outfile.close() 

if __name__ == '__main__': 
    main() 

Toute aide serait grandement appréciée.

+0

Essayez de le déboguer. –

+1

Combien de threads créez-vous? –

Répondre

1

Il semble que vous essayez de démarrer trop de threads.

Vous pouvez vérifier le nombre d'articles dans la liste [address.strip() for address in intext if address.strip()]. Je suppose que c'est un problème ici. Fondamentalement, il existe une limite de ressources disponibles qui permet de démarrer de nouveaux threads.

La solution pour cela est de morceau votre liste de morceaux, disons 20 éléments, faire les choses (dans 20 fils de discussion), attendez fils pour terminer leur travail, puis ramasser morceau suivant. Faites-le jusqu'à ce que tous les éléments de votre liste soient traités.

Vous pouvez également utiliser un pool de threads pour une meilleure gestion des threads. (J'ai récemment utilisé this implementation).

+0

Cela semble être une bonne idée. Merci – Tom

+0

Content de pouvoir vous aider – dzida

1

Il y a probablement une limite supérieure au nombre de threads que vous pouvez créer, et vous le dépassez probablement. Suggestion: Créez un petit nombre fixe de résolveurs - moins de 10 vous obtiendrez probablement 90% de l'avantage de parallélisme possible - et une file d'attente (threadsafe) de la librairie de python. Avoir le thread principal vider tous les domaines dans la file d'attente, et chaque résolveur prendre un domaine à la fois de la file d'attente et travailler dessus.

Questions connexes