2010-06-26 83 views
1

我正在编写一个python脚本来读取域列表,找出Mcafee的Siteadvisor服务提供的评级,然后将域和结果输出到CSV。我该如何解决这个多线程的Python脚本?

我已经将我的脚本关闭了this previous answer。它使用urllib来抓取有问题域名的Siteadvisor页面(不是最好的方法,我知道,但Siteadvisor没有提供其他选择)。不幸的是,它没有生产任何东西 - 我一直得到这个错误:

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 

这里是我的脚本:

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() 

任何帮助将不胜感激。

+0

尝试调试它。 – 2010-06-26 00:24:03

+1

您创建了多少个线程? – 2010-06-26 00:24:54

回答

1

它看起来像你试图启动太多的线程。

您可以检查[address.strip() for address in intext if address.strip()]列表中有多少项。我认为这是一个问题。基本上可用资源有限,可以启动新线程。

解决方法是将你的列表分块为20个元素,做20个线程中的东西,等待线程完成他们的工作,然后拿起下一个块。执行此操作,直到处理完列表中的所有元素。

您还可以使用一些线程池来更好地管理线程。 (我最近使用this implementation)。

+0

听起来像个好主意。谢谢 – Tom 2010-06-26 00:53:21

+0

很高兴我能帮助你 – dzida 2010-06-26 17:10:13

1

您可以创建的线程数可能有一个上限,并且您可能超过了它。建议:创建一个小的固定数量的Resolvers - 在10以下可能会使您获得可能的并行性优势的90% - 以及来自python队列库的(线程安全)队列。让主线程将所有域转储到队列中,并让每个Resolver一次从队列中取一个域并对其进行处理。