【问题标题】:pyinstaller and geckodriver generate issue after compile to exepyinstaller 和 geckodriver 编译为 exe 后产生问题
【发布时间】:2017-12-11 06:27:42
【问题描述】:

我希望我能在这里得到帮助。我正在编写每两分钟读取并导出到 txt '设备实时记录事件'的程序。一切正常,直到我生成 exe 文件。更有趣的是,程序适用于我的环境(安装了 geckodriver 和 python 库),但不适用于没有 python 环境的计算机。即使我使用 --onedir 生成 exe。 有什么想法或提示吗?部分代码如下(没有 tkinter):

browser = webdriver.Firefox()

def logs():
    global writing
    global browser
    logs_content = browser.find_element_by_css_selector(".content")
    if writing:
        curent_time = datetime.datetime.now()
        threading.Timer(120, logs).start()
        save_path = 'C:/Users/' + getpass.getuser() + '/Desktop/Logs ' + curent_time.strftime("%d-%B-%Y") + '.txt'
        with open(save_path, "w") as logs_txt:
            logs_txt.write(logs_content.text)

def enter_to_IDE():
    username = browser.find_element_by_id("username")
    username_input = login.get()
    username.send_keys(username_input)
    browser.find_element_by_id("next-step-btn").click()
    time.sleep(5)
    password_css = browser.find_element_by_id("password")
    password_input = password.get()
    password_css.send_keys(password_input)
    browser.find_element_by_id("login-user-btn").click()
    time.sleep(10)
    logs()

def US_shard():
    global browser
    browser.get('link')
    enter_to_IDE()


def EU_shard():
    global browser
    browser.get('link')
    enter_to_IDE()

【问题讨论】:

  • 提示:阅读文档。 Python 不是为了构建 .exe 而创建的,所以像 pyinstller 这样的程序有时会在查找所有需要的文件时遇到问题。但它有用于配置的特殊文件,您可以在其中手动添加丢失的文件。
  • 见文档Using Spec Files

标签: python-3.x selenium-webdriver tkinter pyinstaller gecko


【解决方案1】:

为未来的谷歌用户...

如果您在使用pyinstaller 构建Selenium python 脚本可执行文件时遇到问题

  1. 阅读上面furas的链接和cmets

  2. 通过编辑 .spec 文件或使用 --add-data ="<gecko location>;<build location>" 将 geckodriver 添加到您的构建中

  3. Default WebDriver 构造函数(上面使用)搜索您的 PATH 以找到 geckodriver,因此如果驱动程序不在系统 PATH 中,您需要告诉您的代码在哪里查找驱动程序

    • 用户Andrew,有一个很好的例子here

第 3 步的问题在于获得一个“位置”,它既可以在您的本地解释器中使用,也可以在您构建的可执行文件中使用。 PC 上的硬编码位置在 exe 文件中不起作用。所以注意--add-data中的来源和目的地,可能使用相对路径。

因为我正在使用一个包含许多用户的存储库,所以我最终没有使用“一体化”选项。相反,我编写了复制geckodriver.exe 以及我的sample.exe 文件的说明。

此 2 文件解决方案不需要 exe 文件中的 geckodriver。因为 Windows 在搜索 PATH 时首先检查您所在的本地文件夹。 source

希望这足以帮助未来的访问者。还要检查此链接以获取 pyinstaller 中的命令

https://pyinstaller.readthedocs.io/en/stable/usage.html#options-group-what-to-bundle-where-to-search

【讨论】:

  • 你好。我实际上正在使用 pyinstaller 打包一个 selenium 应用程序,但我无法完成这项工作。我需要一个 exe 文件,它能够在最终用户不需要 geckodriver 的情况下工作。这可能吗?
  • 我相信这是可能的,但我从来没有让它完全正确地工作。我编译的 EXE 在看到 geckodriver 时遇到问题。看看我的第 3 步和 Andrews 示例的链接。
  • 感谢布赖恩的回复。经过相当多的测试,我实际上已经使它工作了。我使用带有以下代码的 pyinstaller: pyInstaller.exe --noconsole --onefile --add-data "C:\Users\user\documents\Drivers\chromedriver.exe;Drivers" 在 python 脚本中,我使用: driverpath = resource_path ('Drivers\chromedriver.exe') driver = webdriver.Chrome(executable_path = driverpath)
【解决方案2】:

所以我不想吹嘘我的旧答案,我在让它专门用于 Firefox/Geckodriver 时遇到了问题编辑: 这也适用于 FF,我认为我的问题是 Firefox 的较新版本和 geckodriver 版本不兼容。我还没有找到一个新版本的 FF 可以工作。我正在使用 60.1 ESR。 /结束编辑

但我也刚刚在几秒钟前找到了 Chrome/Chromedriver 的解决方案。 我也不再使用 Firefox 了 :-( 我仍然是,但我们正在逐步淘汰它 :-(

但这可能适用于最新版本的 Selenium 和 Geckodriver。

这是我得到的。这个问题有两个方面。

  1. 当以.py.exe 运行时,需要告诉你的python 代码在哪里寻找你的WebDriver
  2. 需要运行 PyInstaller 应用,并指定正确的目录。

问题是,PyInstaller 将所有内容提取到 TEMP 目录中。 (对于 Windows,它通常是 %TEMP%/_MEIxxxxx 其中 XXXXX 是每个实例的随机数(允许同时运行副本)。一旦您编译的 python .exe 完成运行(或由于 Selenium 找不到驱动程序而崩溃),此目录将被删除. 此外,此目录很可能与您的项目文件夹不同。

第 1 节,python 代码。

项目结构 来源/chromedriver.exe main.py

import sys
import time
from selenium import webdriver

if hasattr(sys, "_MEIPASS"):
    print("TEMP PATH IS: %s " % sys._MEIPASS)
    work_dir = sys._MEIPASS
else:
    print("didn't have it")
    work_dir = os.getcwd()

time.sleep(20) # allows you to visually inspect the path above, shorten time at your discretion

chrome_driver_path = os.path.normpath(os.path.join(work_dir, "Sources/chromedriver.exe"))
driver = webdriver.Chrome(executable_path=chrome_driver_path )
driver.get("https://www.google.com")
time.sleep(10) # allows you to verify the page loaded

第 2 节 - PyInstaller

将其输入到项目文件夹中的命令提示符中,或将其放入批处理文件中。

python -m PyInstaller ^
--onefile ^
--noconfirm ^
--name="main.exe" ^
--add-data="Sources\chromedriver.exe" ^
--clean ^
"main.py"

--noconfirm--clean 这样的一些标志对于批处理来说不是很需要,但是当你再次编译时它会强制PyInstaller 覆盖EXE。 此外,如果直接在终端/命令提示符中输入,插入符号 ^ 可以省略,因为您很可能不会使用换行符(输入键)

软件版本

Python 2.7.14 
selenium==3.14.1 
Chrome (64 bit) 85.0.4183.83
chromedriver --version ChromeDriver 85.0.4183.83 (win32.zip)

酱汁:-)

  1. https://pyinstaller.readthedocs.io/en/stable/operating-mode.html#how-the-one-file-program-works
  2. https://chromedriver.chromium.org/downloads
  3. Packaging a script and data file using PyInstaller - how to use resource_path()(用于 _MEIxxxxx 临时文件夹)

【讨论】:

    猜你喜欢
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 2018-11-11
    • 2022-08-05
    • 1970-01-01
    • 2022-11-02
    相关资源
    最近更新 更多