pyinstaller 和 geckodriver 在编译为 exe 后产生问题 [英] pyinstaller and geckodriver generate issue after compile to exe

查看:60
本文介绍了pyinstaller 和 geckodriver 在编译为 exe 后产生问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我能在这里得到帮助.我正在编写程序,该程序将每两分钟读取一次设备实时日志记录事件"并将其导出到 txt.一切正常,直到我生成 exe 文件.更有趣的是,程序可以在我的环境中运行(安装了 geckodriver 和 python 库),但在没有 python 环境的计算机上不起作用.即使我用--onedir生成exe.任何想法或提示?部分代码如下(没有 tkinter):

I hope i will get help here. I'm writing program who will read and export to txt 'devices live logging events' every two minutes. Everything works fine until i generate exe file. What is more interesting, program works on my enviroment(geckodriver and python libraries installed), but does not work on computers without python enviroment. Even if I generate exe with --onedir. Any ideas or tips? part of code is below(without 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()

推荐答案

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

So i didn't want to blow away my old answer, I had issues getting this to work with Firefox/Geckodriver specifically. this works with FF also, I think my issue was a newer version of Firefox and an incompatible geckodriver version. I have not found a newer version of FF that works. I'm using 60.1 ESR. /End Edit

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

But I also just found out a solution to Chrome/Chromedriver a few seconds ago. Also I'm not working with Firefox anymore :-( I still am, but we are phasing it out :-(

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

But this might work with recent versions of Selenium and Geckodriver.

这是我得到的.这个问题有两部分.

Here is what I got. There are two halves to this problem.

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

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

The problem is, PyInstaller extracts everything to a TEMP directory. (for windows it's usually %TEMP%/_MEIxxxxx where XXXXX is a random number for each instance (allows for simultaneous running copies). This directory is deleted once your complied python .exe is finished running (or crashes because Selenium can't find the driver). Also this directory is most likely different from your Project Folder.

项目结构来源/chromedriver.exe主文件

Project Structure Sources/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

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

Section 2 - PyInstaller

enter this into a command prompt working out of your project folder, or put this into a batch file.

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

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

some of the flags like --noconfirm, and --clean are not quite needed for the batch, but it forces PyInstaller to overwrite the EXE when you compile again. Also if typing directly in a terminal/command prompt the carets ^ can be omitted as you will most likely not be using newlines (enter key)

软件版本

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. 打包脚本和使用 PyInstaller 的数据文件 - 如何使用 resource_path()(用于 _MEIxxxxx Temp 文件夹)
  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() (for _MEIxxxxx Temp folder)

这篇关于pyinstaller 和 geckodriver 在编译为 exe 后产生问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆