You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中传递Selenium实例至新进程出现异常问题

无法在多进程间传递Selenium Driver实例的问题

报错信息

Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "c:\Users\user\Desktop\coding\PokeClicker Bot\Version 3 (Gui) (WIP)\version3.py", line 37, in <lambda>
    item = tk.Button(root, text='Run', relief='raised', command=lambda:toggle(item))
  File "c:\Users\user\Desktop\coding\PokeClicker Bot\Version 3 (Gui) (WIP)\version3.py", line 54, in toggle
    startRun()
  File "c:\Users\user\Desktop\coding\PokeClicker Bot\Version 3 (Gui) (WIP)\version3.py", line 62, in startRun
    p.start()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 121, in start
    self._popen = self._Popen(self)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\multiprocessing\context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\multiprocessing\context.py", line 327, in _Popen
    return Popen(process_obj)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__
    reduction.dump(process_obj, to_child)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
TypeError: cannot pickle '_io.TextIOWrapper' object
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.3568.0_x64__qbz5n2kfra8p0\lib\multiprocessing\spawn.py", line 126, in _main
    self = reduction.pickle.load(from_parent)
EOFError: Ran out of input

精简代码

def init():
    global ffD
    ffD = WD.Firefox(os.getcwd(), options=options)
    ffD.get('https://www.pokeclicker.com/')
    root.mainloop()
    
def runThroughDungeon(driver): #Currently just driver.close() to test.
    driver.close()

def startRun(): #Called from toggling tkinter button.
    global p
    p = mp.Process(target = runThroughDungeon, args=(ffD,))
    p.start()

def stopRun():
    p.kill()

if __name__ == '__main__':
    init()

问题原因

Selenium的WebDriver实例无法通过Python的序列化(pickle)机制传递给子进程。因为WebDriver内部包含大量无法被序列化的资源,比如_io.TextIOWrapper文件对象、浏览器进程的底层连接句柄等。Windows系统下的multiprocessing默认使用spawn启动方式,会重新初始化Python解释器,要求所有传递给子进程的参数必须能被序列化,因此直接传递Driver实例会触发报错。

解决方案

方案1:在子进程内初始化WebDriver

不再在主进程创建Driver实例,而是让子进程自行启动浏览器、执行任务并关闭,避免跨进程传递无法序列化的对象:

def runThroughDungeon():
    # 子进程内初始化Driver
    ffD = WD.Firefox(os.getcwd(), options=options)
    ffD.get('https://www.pokeclicker.com/')
    # 执行你的业务逻辑
    ffD.close()

def startRun():
    global p
    p = mp.Process(target=runThroughDungeon)
    p.start()

方案2:改用线程替代多进程

如果需要复用主进程的Driver实例,可以使用threading模块。线程共享主进程的内存空间,不需要序列化对象,直接传递Driver实例即可。注意:tkinter的UI操作必须在主线程执行,但Selenium的操作可以在子线程中进行:

import threading

def runThroughDungeon(driver):
    driver.close()

def startRun():
    global p
    p = threading.Thread(target=runThroughDungeon, args=(ffD,))
    p.start()

内容的提问来源于stack exchange,提问作者cheis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:45:45