2017-02-25 62 views
1

立即返回我已经写了一对夫妇在python Twitter的刮削器,并在写另一个脚本,让他们即使他们遭受超时,断开跑步等Python模块功能的线程

我目前的解决方案是如下:

每一刮片文件中有一个doScrape/1功能,这将启动刮板,一旦运行,如:

def doScrape(logger): 
    try: 
     with DBWriter(logger=logger) as db: 
      logger.log_info("starting", __name__) 
      s = PastScraper(db.getKeywords(), TwitterAuth(), db, logger) 
      s.run() 
    finally: 
     logger.log_info("Done", __name__) 

其中行程是接近无限的循环,从而赢得除非有例外情况,否则不得中断。

为了运行各种刷屏之一一次,我用这个代码(有一些额外的进口):

from threading import Thread 

class ScraperThread(Thread): 
    def __init__(self, module, logger): 
     super(ScraperThread, self).__init__() 
     self.module = module # Module should contain a doScrape(logger) function 
     self.logger = logger 


    def run(self): 
     while True: 
      try: 
       print "Starting!" 
       print self.module.doScrape 
       self.module.doScrape(self.logger) 
      except: # if for any reason we get disconnected, reconnect 
       self.logger.log_debug("Restarting scraper", __name__) 

if __name__ == "__main__": 
    with Logger(level="all", handle=open(sys.argv[1], "a")) as l: 
     past = ScraperThread(PastScraper, l) 
     stream = ScraperThread(StreamScraper, l) 
     past.start() 
     stream.start() 
     past.join() 
     stream.join() 

然而,看来我从上面doScrape的呼叫立即返回,因此“开始!”被印刷在控制台反复,而“完成”中的最后块消息不写入日志,而像这样单独运行时:

if __name__ == "__main__": 
    # Example instantiation 
    from Scrapers.Logging import Logger 
    with Logger(level="all", handle=open(sys.argv[1], "a")) as l: 
     doScrape(l) 

的代码运行永远,如所预期。我有点难住。

我可能错过了什么愚蠢的东西吗?

+0

因此,如果你调用'doScrape'而不是如果你调用'PastScraper.doScrape'或'StreamScraper.doScrape',它会有效吗? –

回答

0

啊哈,解决了它!实际上,我没有意识到在定义时间评估默认参数(这里是在TwitterAuth()中)。 TwitterAuth从文件句柄读取API密钥设置,默认参数打开默认配置文件。由于此文件句柄是在定义时生成的,因此两个线程都具有相同的句柄,一旦有人读取它,另一个线程尝试从文件末尾读取,抛出异常。这可以通过在使用前重置文件并使用互斥锁来解决。

向Irmen de Jong欢呼,指引我朝着正确的方向前进。

1

摆脱run()方法中的尿布模式,如下所示:摆脱捕捉所有异常处理程序。那么你可能会在那里打印错误。我认为 DBWriter或您从doScrape函数调用的其他代码可能有问题。也许它不是线程安全的。这可以解释为什么从主程序直接运行它,但从线程调用它失败。