python - 如何使用 PyInstaller 在 MacOS 上使用 selenium/chrome webdriver 制作独立的 Python 可执行文件
问题描述
我正在尝试制作使用 selenium 和 webdriver 的 webscraping 脚本的独立可执行文件,并且我希望能够将文件共享给其他用户,而无需他们手动安装 chromedriver 并指定其路径。
当我在同一目录中使用 chromedriver 运行可执行文件时,我在终端中得到以下输出:
Traceback (most recent call last):
File "site-packages/selenium/webdriver/common/service.py", line 76, in start
File "subprocess.py", line 707, in __init__
File "subprocess.py", line 1326, in _execute_child
FileNotFoundError: [Errno 2] No such file or directory: 'chromedriver'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "excelRW.py", line 336, in <module>
File "site-packages/selenium/webdriver/chrome/webdriver.py", line 73, in __init__
File "site-packages/selenium/webdriver/common/service.py", line 83, in start
selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home
在我的脚本中,这就是我初始化 webdriver 的内容:
driver = webdriver.Chrome()
我确实在这里找到了类似的问题/答案: Create a Python executable with chromedriver & Selenium
但我不确定如何在 MacOS 上进行这项工作;我在这里尝试了这个规范文件,但是当我运行 /dist/excelRW.py 时,它给了我与上面相同的输出:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['excelRW.py'],
pathex=['/Users/graememjehovich/Desktop/House Districting Script'],
binaries=[('/Users/graememjehovich/Desktop/House Districting Script/chromedriver', '**./selenium/webdriver**')],
datas=[],
hiddenimports=[],
hookspath=[],
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='excelRW',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='**excelRW.py**')
解决方案
也许使用WebDriverManager,它会在运行时下载最新的 webdriver,所以你根本不需要发布它。这也解决了您的用户在升级 Chrome 版本时可能遇到的问题,因为 Chrome 版本和驱动程序需要匹配。因此,如果您在安装程序中对驱动程序版本进行硬编码,则抓取工具将在用户升级浏览器后停止工作,这在 Chrome 中会自动发生。
我这样使用它:
from webdriver_manager.chrome import ChromeDriverManager
webdriver.Chrome(ChromeDriverManager().install())
推荐阅读
- ios - AWSCognito/DynamoDB 问题(未经身份验证的访问 - 不支持)
- php - 我已经在我的 macOs Mojave 上安装了 php trade 扩展,但我无法使用它
- julia - 没有方法匹配 write(::IOStream, ::MyClass)
- rust - Rust 中有传统风格的 switch 语句吗?
- sonarqube - SonarQube - 具有相同方法签名但不提供类的两个方法
- html - 关于html单选输入取消选择的问题
- git - 在 git log 中获取文件重命名前后的完整文件路径
- java - MyBatis 3.4.5;@SelectProvider 不替换参数占位符
- node.js - passport.authenticate 没有被执行
- c++ - lock_guard 导致代码行挂起