❤️ 踩坑记录
2026-06-20 · 约5分钟阅读

PyInstaller打包exe的依赖坑:--hidden-import全记录

自动化 部署 PyInstaller

问题现象

脚本在本地跑得好好的,打包成 exe 之后,双击运行直接闪退。去命令行手动运行,看到了这个:

ModuleNotFoundError: No module named 'selenium.webdriver'

明明打包成功了,怎么还找不到模块?

根本原因

PyInstaller 的依赖分析是静态的——它只会打包代码中显式 import 的模块。但很多库用的是动态导入:

# selenium 内部会动态导入 webdriver 模块
# PyInstaller 分析不到,就不会打包进去

解决方案:--hidden-import

手动告诉 PyInstaller 这些"隐身"的依赖:

pyinstaller ^
  --onefile ^
  --hidden-import selenium.webdriver ^
  --hidden-import selenium.webdriver.chrome.service ^
  --hidden-import selenium.webdriver.common.by ^
  MSDrpa.py

我遇到的完整 hidden-import 清单

这些是 MSD 自动化项目打包时踩出来的,供参考:

# Selenium 相关(最常见)
--hidden-import selenium.webdriver
--hidden-import selenium.webdriver.chrome.service
--hidden-import selenium.webdriver.chrome.options
--hidden-import selenium.webdriver.common.by
--hidden-import selenium.webdriver.support.ui
--hidden-import selenium.webdriver.support.expected_conditions

# 如果用到无头模式
--hidden-import selenium.webdriver.chrome.webdriver

# openpyxl(处理Excel)
--hidden-import openpyxl.cell._writer
--hidden-import openpyxl.worksheet._reader

# PIL/Pillow(截图用)
--hidden-import PIL._imaging
--hidden-import PIL._imagingtk

# 动态 import 的自定义模块
--hidden-import my_module.sub_module

更好的方案:用 .spec 文件

命令行参数太长,维护困难。改用 .spec 文件:

# msdrpa.spec
block_cipher = None

a = Analysis(
    ['MSDrpa.py'],
    pathex=[],
    binaries=[],
    datas=[],
    hiddenimports=[
        'selenium.webdriver',
        'selenium.webdriver.chrome.service',
        'selenium.webdriver.common.by',
        'selenium.webdriver.support.ui',
        'selenium.webdriver.support.expected_conditions',
        'openpyxl',
    ],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='MSDrpa',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=True,   # 改成 False 可隐藏命令行窗口
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

然后运行:

pyinstaller msdrpa.spec
✅ 调试技巧:打包时加 --debug all 可以看到详细的导入失败信息,比盲目加 hidden-import 高效得多。

终极武器:pyinstaller-hooks-contrib

很多常见库的 hook 已经有了,安装这个包可以自动处理很多 hidden-import:

pip install pyinstaller-hooks-contrib

安装后重新打包,Selenium、openpyxl 等常见库的 hidden-import 会自动处理,不需要手动指定。