pyinstaller和geckodriver在编译为exe

时间:2017-12-11 06:27:42

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

我希望我能在这里得到帮助。我正在编写程序,每隔两分钟就会读取并导出到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()

2 个答案:

答案 0 :(得分:0)

面向未来的Google用户...

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

  1. 阅读上面furas的链接和评论

  2. 通过编辑.spec文件或使用--add-data ="<gecko location>;<build location>"

  3. 将geckodriver添加到您的构建中
  4. 默认的WebDriver构造函数(上面使用过)在PATH中搜索以找到geckodriver,因此,如果驱动程序不在系统PATH中,则需要告诉代码在哪里寻找驱动程序

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

第3步遇到的麻烦是获得一个“位置”,该位置在您的本地解释器和已构建的可执行文件中均有效。 exe文件中无法在PC上使用硬编码位置。因此,请注意--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

答案 1 :(得分:0)

所以我不想遗忘我的旧答案,我在使它专门用于Firefox / Geckodriver时遇到问题。但几秒钟前,我也刚刚找到了针对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 Temp文件夹)