【问题标题】:How to handle Python's threading.Thread exceptions?如何处理 Python 的 threading.Thread 异常?
【发布时间】:2016-02-10 13:58:11
【问题描述】:

我正在使用 Selenium 运行两个 Firefox 实例并获取特定页面。 我正在使用threading.Thread 为每个页面并行加载页面。 我还想为最大页面加载时间设置超时,在我的代码中使用browser.set_page_load_timeout()

我的整个代码如下所示:

from selenium import webdriver
from threading import Thread
from selenium.common.exceptions import TimeoutException


class Test():
        def __init__(self):
            browser = webdriver.Firefox()

            def load_page(browser, url):
                browser.set_page_load_timeout(20)
                browser.get(url)

            t = Thread(target=load_page, args=(browser, 'http://www.stackoverflow.com', ))
            t.start()
            t.join()

if __name__ == '__main__':
    try:
        Test()
    except TimeoutException:
        print "timeout reached"

尽管我声明了try except,但我仍然收到此错误:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
    self.run()
  File "C:\Python27\lib\threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "C:\Temp\test_b.py", line 13, in load_page
    browser.get(url)
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 213, in get
    self.execute(Command.GET, {'url': url})
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 201, in execute
    self.error_handler.check_response(response)
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 181, in check_response
    raise exception_class(message, screen, stacktrace)
TimeoutException: Message: Timed out waiting for page load.
Stacktrace:
    at Utils.initWebLoadingListener/< (file:///c:/users/mgal/appdata/local/temp/tmpsasxck/extensions/fxdriver@googlecode.com/components/driver-component.js:9010)
    at WebLoadingListener/e (file:///c:/users/mgal/appdata/local/temp/tmpsasxck/extensions/fxdriver@googlecode.com/components/driver-component.js:5114)
    at WebLoadingListener/< (file:///c:/users/mgal/appdata/local/temp/tmpsasxck/extensions/fxdriver@googlecode.com/components/driver-component.js:5122)
    at fxdriver.Timer.prototype.setTimeout/<.notify (file:///c:/users/mgal/appdata/local/temp/tmpsasxck/extensions/fxdriver@googlecode.com/components/driver-component.js:621)

总之,我怎样才能在线程范围之外捕获超时异常? 先谢谢了!

【问题讨论】:

    标签: python multithreading exception-handling python-multithreading


    【解决方案1】:

    线程子进程在他们自己的堆栈中运行,因此如果没有消息/事件传递,这是不可能的。您可以使用 python 的 Queue 库(它是线程安全的)并将队列对象传递给您的子函数,将其用作父函数可以处理的事件池。

    【讨论】:

      【解决方案2】:

      你不能。您应该在线程中处理异常,因此您的函数应该或多或少类似于:

      def load_page(browser, url):
          try:
              browser.set_page_load_timeout(20)
              browser.get(url)
          except TimeoutException:
              '''Handle me here'''
      

      编辑:您实际要求的是:

      from selenium import webdriver
      from threading import Thread
      from Queue import Queue
      from selenium.common.exceptions import TimeoutException
      
      
      class Test():
              def __init__(self, queue, url):
                  browser = webdriver.Firefox()
      
                  def load_page(browser, url):
                      try:
                          browser.set_page_load_timeout(20)
                          browser.get(url)
                      except Exception as e:
                          queue.put(e)
                      else:
                          queue.put('OK or whatever the result you want')
      
                  t = Thread(target=load_page, args=(browser, url, ))
                  t.start()
      
      if __name__ == '__main__':
          urls = ('http://www.stackoverflow.com', 'http://http://meta.stackoverflow.com/')
          queue = Queue()
          for url in urls:
              Test(queue, url)
          for i in range(len(urls)):
              result = queue.get()
              if isinstance(result, Exception):
                  '''Handle exception preferably trying to determine the actual exception type'''
              else:
                  '''Say cool cause everything is fine'''
      

      【讨论】:

      • 您可以在线程中捕获异常,并使用队列将异常对象传递给主线程。但首先,您的代码没有利用线程的任何优势,因为您总是在启动线程后立即等待线程加入。这样,您将始终获得性能比没有线程更差的顺序执行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多