【问题标题】:ImportError: sys.meta_path is None, Python is likely shutting down error using driver.quit() within __del__()ImportError: sys.meta_path 为 None,Python 可能会在 __del__() 中使用 driver.quit() 关闭错误
【发布时间】:2020-11-14 08:10:41
【问题描述】:

我正在尝试学习 selenium 以使某些东西自动化,但出现以下错误

异常被忽略:del at 0x0351BF10>
回溯(最近一次通话最后一次):
del
中的文件“main.py”,第 52 行 文件“C:\Users\michael-blaze\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\chrome\webdriver.py”,第 158 行, 在退出
文件“C:\Users\michael-blaze\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\common\service.py”,第 151 行,停止
文件“C:\Users\michael-blaze\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\common\service.py”,第 122 行,在 send_remote_shutdown_command
ImportError: sys.meta_path 为 None,Python 可能正在关闭

我知道它的来源

def __del__(self):
   self.driver.quit()

我的 init 函数看起来像这样

def __init__(self):
   self.driver = webdriver.Chrome(path)

什么会导致这个问题?

【问题讨论】:

  • 最初我读了那篇文章,但不幸的是它没有解决我的问题
  • 您能否重新考虑您的代码以改用with webdriver.Chrome(path):?最后应该正确清理
  • 我仍然是 python 的菜鸟。当你说使用'with webdriver.Chrome(path)'时你能更具体一点吗:)
  • self.driver.close() 工作,但它不会释放内存运行。t

标签: python selenium selenium-webdriver webdriver del


【解决方案1】:

我能够重现您的问题。以下是观察结果:

  • 代码块:

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
    class PythonBot:
        def __init__(self,my_string):
        self.my_string = my_string
        self.driver = webdriver.Chrome(executable_path=r'C:\WebDrivers\chromedriver.exe')
    
        def send_text(self):
        driver = self.driver
        driver.get('https://www.google.com/')
        WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.NAME, "q"))).send_keys(self.my_string)
    
        def __del__(self):
        self.driver.quit()
    
    run = PythonBot('Selenium')
    run.send_text()
    
  • 控制台输出:

    Exception ignored in: <bound method PythonBot.__del__ of <__main__.PythonBot object at 0x028172F0>>
    Traceback (most recent call last):
      File "C:\Users\Soma Bhattacharjee\Desktop\Debanjan\PyPrograms\init_del_in_python_class.py", line 17, in __del__
      File "C:\Python\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 158, in quit
      File "C:\Python\lib\site-packages\selenium\webdriver\common\service.py", line 151, in stop
      File "C:\Python\lib\site-packages\selenium\webdriver\common\service.py", line 122, in send_remote_shutdown_command
    ImportError: sys.meta_path is None, Python is likely shutting down
    

分析

这个问题早先在sys.meta_path is None, Python is likely shutting down 中报告和讨论过。因此,commit 被合并,其中提到:

更改事件的顺序以停止进程。之前。订单是terminate() -> kill() -> wait()。所以......它会向进程发送一个 SIGTERM 信号,然后立即发送一个 SIGKILL 信号。因为wait()是在进程被强制停止后调用的,所以没有什么可以等待的,所以它什么也不做。正确的顺序应该是:terminate() -> wait() -> kill()。这将发送一个 SIGINT,等待进程正常终止,然后发送一个 SIGKILL 以强制停止它作为最后的手段。

但是,当在def __del__(self): 中使用self.driver.quit() 时,这个问题似乎仍然浮出水面

报告了这个问题:


临时解决方案

临时解决方案是在def __del__(self): 中调用self.driver.close(),如下所示:

def __del__(self):
    self.driver.close()

【讨论】:

    【解决方案2】:

    看看你是否可以像这样构造你的代码:

    # stuff before the driver call
    with webdriver.Chrome(path) as driver:
        # do your stuff here
        # you can access the driver using the variable 'driver'
    # stuff after the driver call
    

    这样,一旦with 块完成,驱动程序应该以最好的方式被清理,包括强制 Python 等到关闭。

    免责声明:我没有测试过,只是注意到他们实现了__enter____exit__ 方法

    【讨论】:

    • 您的方法运行良好,但我仍然想知道为什么 self.driver.quit() 在我的 del 析构函数中不起作用。我想使用类。
    • 这可能是理解该问题的一个很好的参考:*.com/questions/14986568/…。基本上,一旦你到达__del__,你的解释器已经清理了一些东西。查看代码,似乎在quit 命令中导入了一些模块,但这样做可能为时已晚