PyInstaller打包exe运行时无法弹出easygui.enterbox输入框问题
PyInstaller打包EasyGUI脚本闪退问题解决方案
问题背景
开发完成的Python爬虫脚本计划部署到办公室其他设备使用,在IDE环境中运行完全正常,但使用PyInstaller打包为独立exe文件后启动闪退。通过异常捕获逐步定位故障点,最终定位到与EasyGUI输入框相关的逻辑段。
相关代码片段
基金代码输入逻辑
功能为弹出输入框获取用户输入的空格分隔基金、ETF代码,拆分后作为后续爬虫的输入参数:
One_String = easygui.enterbox('list the fund and etf tickers here, space delimeted') try: list_o_tickers = One_String.split() finally: pass
后续爬虫处理逻辑
遍历拆分后的代码列表,拼接晨星网对应URL,校验可访问性后存入待爬列表:
for i in list_o_tickers: AAB = i AAC = 'http://morningstar.com/funds/xnas/' + AAB + '/portfolio' re = req.get(AAC) if re.status_code == 200: URLlist.append(AAC) else: AAC = 'http://morningstar.com/etfs/arcx/' + AAB + '/portfolio' re = req.get(AAC) if re.status_code == 200: URLlist.append(AAC) else: pass
结果导出逻辑
爬虫完成数据抓取生成Pandas数据框后,弹出输入框获取导出路径,拼接文件名后导出为Excel:
outputpath = easygui.enterbox('coppy and past the filepath for the destination folder here') time = datetime.now() strtime = time.strftime("%H-%M-%S") notrawstr = outputpath + '\DataTransfer' + strtime +'.xlsx' rawstr = r'{}'.format(notrawstr) Total_of_Totals.to_excel(rawstr)
异常日志
打包后exe运行生成的错误日志如下,核心报错为AttributeError: 'NoneType' object has no attribute 'split':
Traceback (most recent call last): File "ScraperProject1.py", line 8, in <module> File "<frozen importlib._bootstrap>", line 1027, in _find_and_load File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 688, in _load_unlocked File "PyInstaller\loader\pyimod03_importers.py", line 495, in exec_module File "pyppeteer\__init__.py", line 33, in <module> AttributeError: 'NoneType' object has no attribute 'split'
故障原因初步判断
IDE环境下运行时,easygui.enterbox会阻塞进程等待用户输入完成后再执行后续逻辑;但打包后的exe运行时输入框未正常弹出,程序直接向下执行One_String.split()逻辑,此时One_String为None值,触发属性错误导致闪退。
解决步骤
- 首先补全所有EasyGUI输入的空值兜底逻辑:
easygui.enterbox本身在用户点击取消、关闭窗口、弹窗创建失败时都会返回None,不管是IDE还是打包环境,缺少非空判断本身就有逻辑漏洞。以基金代码输入为例,增加循环校验+异常退出逻辑:
import sys import easygui while True: One_String = easygui.enterbox('list the fund and etf tickers here, space delimeted') # 用户主动取消输入则直接退出程序 if One_String is None: easygui.msgbox("Input canceled, program will exit.") sys.exit(0) # 输入为空则提示重新输入 if not One_String.strip(): easygui.msgbox("Input can not be empty, please try again.") continue list_o_tickers = One_String.split() break
导出路径的输入逻辑也要加同款校验,同时补充路径合法性判断,避免拿到无效路径后续导出报错。
- 解决打包后EasyGUI弹窗不显示的核心问题:如果打包时使用了
-w/--windowed无控制台参数,很容易出现tkinter(EasyGUI依赖的GUI库)依赖缺失导致弹窗创建失败。处理方式:- 初期调试先去掉
-w参数,保留控制台窗口运行,确认弹窗正常弹出、全流程跑通后再调整为无窗口模式 - 正式无窗口打包时,显式声明导入tkinter和easygui依赖,打包命令参考:
pyinstaller -F -w --hidden-import tkinter --hidden-import easygui ScraperProject1.py
- 初期调试先去掉
- 调整模块导入顺序:从报错栈可以看到pyppeteer在脚本启动阶段就被加载,pyppeteer初始化时需要识别本地Chromium路径,打包后路径识别异常也会导致程序在弹窗弹出前就崩溃。把pyppeteer、爬虫相关的重型模块导入放在输入校验通过之后再执行,不要放在脚本开头全局导入,减少启动阶段的异常概率。
内容的提问来源于stack exchange,提问作者Brandon
相关产品推荐
相关产品推荐

