使用request-html的Python代码转exe后运行报错:AttributeError
问题根源
requests-html的render()方法依赖内置Chromium浏览器渲染动态页面,但PyInstaller/auto-py-to-exe默认不会打包Chromium相关文件。exe运行时无法找到浏览器资源,导致内部逻辑对None值执行split操作触发报错。而开发环境(VS Code)中requests-html能自动定位已下载的Chromium,因此运行正常。
解决方案
1. 手动打包Chromium资源并指定路径
步骤1:获取Chromium路径
在开发环境的Python终端执行以下代码,获取requests-html自带的Chromium文件夹路径:
from requests_html import HTMLSession print(HTMLSession().browser.path)
输出类似C:\你的Python路径\Lib\site-packages\pyppeteer\local-chromium\588429\chrome-win\chrome.exe,我们需要保留chrome-win整个文件夹的路径。
步骤2:打包时添加资源
PyInstaller命令行方式:
执行打包命令时,通过--add-data参数将Chromium文件夹打包进exe:pyinstaller --onefile --add-data "C:\你的Python路径\Lib\site-packages\pyppeteer\local-chromium\588429\chrome-win;chrome-win" your_script.py注意:Windows系统用
;分隔源路径和目标路径,Mac/Linux用:。auto-py-to-exe图形界面方式:
在「Additional Files」选项中点击「Add Files」,选择chrome-win文件夹,设置「Destination」为chrome-win后再执行打包。
步骤3:修改代码适配路径
修改原代码,在调用render()时手动指定Chromium路径,同时适配开发和打包后的环境:
from requests_html import HTMLSession import sys import os def get_chrome_path(): if getattr(sys, 'frozen', False): # 打包后的exe环境,从临时目录读取Chromium return os.path.join(sys._MEIPASS, 'chrome-win', 'chrome.exe') else: # 开发环境自动获取路径 return HTMLSession().browser.path url = input("\nEnter Link: ") # url = "https://www.w3schools.com/python/python_variables.asp" s = HTMLSession() r = s.get(url) # 指定Chromium路径渲染页面 r.html.render(sleep=1, executablePath=get_chrome_path()) # 增加元素存在性判断,避免找不到元素时报错 title_elem = r.html.find('span.color_h1', first=True) if title_elem: print(title_elem.text) else: print("未找到目标标题元素")
2. 补充异常处理
原代码未处理目标页面不存在指定元素的情况,增加存在性判断后,能避免这类运行时错误,提升程序健壮性。
验证
打包完成后运行exe,输入测试链接(如示例中的w3schools链接),即可正常渲染并输出标题。
内容的提问来源于stack exchange,提问作者Prottoy

