重构 PySimpleGUI 以弹出 select selenium 驱动程序而不是下拉

Refactor PySimpleGUI to give pop up to select selenium driver instead of drop down

我构建了一个 PySimpleGUI 应用程序,它 select 是一个 CSV,让你 select 一个 Chrome 版本,然后使用 Selenium 进行表单输入和提交。但是,我现在需要将下拉菜单重构为 select,就像 CSV 的工作方式一样,但无法使其正常工作,我的代码

import csv
import time
import threading
from selenium import webdriver
import PySimpleGUI as sg
import os
import sys


def resource_path(relative_path):

  try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
    base_path = sys._MEIPASS
  except Exception:
    base_path = os.path.abspath(".")

  return os.path.join(base_path, relative_path)



def make_window(theme):

    sg.theme(theme)
    menu_def = [['&Application', ['E&xit']],
                ['&Help', ['&About']] ]
    right_click_menu_def = [[], ['Exit']]

    # Table Data


    input_layout =  [[sg.Menu(menu_def, key='-MENU-')],
                 
                
                [sg.Button("Open File")],
               
                [sg.Text('Chrome Version')],

                [sg.OptionMenu(values=('96', '97', '98'),  k='-OPTION MENU-'),],
               
                [sg.Button('Submit')]]



    
    
    layout = [[sg.Text(' Email Automation', size=(38, 1), justification='center', font=("Helvetica", 16), relief=sg.RELIEF_RIDGE, k='-TEXT HEADING-', enable_events=True)]]
    layout +=[[sg.TabGroup([[  sg.Tab('Setup CSV and Chrome Version', input_layout),
                               
                               ]], key='-TAB GROUP-')]]
              
    return sg.Window('TEST', layout, right_click_menu=right_click_menu_def)


def main():
    window = make_window(sg.theme())
    
    # This is an Event Loop 
    while True:
        event, values = window.read(timeout=100)
        # keep an animation running so show things are happening
       
        if event not in (sg.TIMEOUT_EVENT, sg.WIN_CLOSED):
            print('============ Event = ', event, ' ==============')
            print('-------- Values Dictionary (key=value) --------')
            for key in values:
                print(key, ' = ',values[key])
        if event in (None, 'Exit'):
            print("[LOG] Clicked Exit!")
            break
        elif event == 'About':
            print("[LOG] Clicked About!")
            sg.popup('TEST email automation',
                     'Select CSV file',
                     'Select Chrome Version',
                     'Submit',
                     'Powered By Me')
        elif event == 'Popup':
            print("[LOG] Clicked Popup Button!")
            sg.popup("You pressed a button!")
            print("[LOG] Dismissing Popup!")


        elif event == "Open File":
            print("[LOG] Clicked Open File!")
            csv_file_selected = sg.popup_get_file('Choose your file')
            # sg.popup("You chose: " + str(folder_or_file))
            # print("[LOG] User chose file: " + str(folder_or_file))




def run_selenium(window, file, driver):

    with open(file, 'rt') as csv_file:
        csv_reader = csv.reader(csv_file)
    #-------------------------------------------------------------------------------
    # Web Automation
    driver = webdriver.Chrome(executable_path=driver,service_log_path='/dev/null')
    driver.get('https:/')
  
    
    fname_field = driver.find_element_by_xpath('//*[@id="FIRSTNAME"]')
    lname_field = driver.find_element_by_xpath('//*[@id="LASTNAME"]')
    phone_field = driver.find_element_by_xpath('//*[@id="PHONE"]')
    mail_field = driver.find_element_by_xpath('//*[@id="EMAIL"]')
    deposit_field = driver.find_element_by_xpath('//*[@id="DEPOSIT"]')
    submit = driver.find_element_by_xpath('//*[@id="sib-form"]/div[8]/div/button')

    with open(file, 'rt', encoding='utf-8-sig') as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=';')
        next(csv_reader)
        for line in csv_reader:
            
            time.sleep(2.5)
            
            fname_field.send_keys(line[10])
            lname_field.send_keys(line[11])
            mail_field.send_keys(line[13])
            phone_field.send_keys(line[16])
            deposit_field.send_keys(line[37])
            submit.click()
        
        

    # Not to update GUI in thread, but generate an event which will be processed in event loop.
    window.write_event_value('Done', None)

def main():
    # My GUI
    window = make_window(sg.theme())
    folder_or_file = None
    cdriver = resource_path('chromedriver.exe')
    # Using your path for all the drivers of all versions
    paths = {
        #'96': './chromedriver.exe',
        '96': cdriver,
        
    }

    while True:
        event, values = window.read(timeout=100)
        # keep an animation running so show things are happening

        if event not in (sg.TIMEOUT_EVENT, sg.WIN_CLOSED):
            # print('============ Event = ', event, ' ==============')
            # print('-------- Values Dictionary (key=value) --------')
            for key in values:
               print(key, ' = ',values[key])
        if event in (None, 'Exit'):
           # print("[LOG] Clicked Exit!")
            break
        elif event == 'About':
           # print("[LOG] Clicked About!")
            sg.popup('email',
                     'Select CSV file',
                     'Select Chrome Version',
                     'Submit',
                     '')
        elif event == 'Popup':
           # print("[LOG] Clicked Popup Button!")
            sg.popup("You pressed a button!")
           # print("[LOG] Dismissing Popup!")
        elif event == "Open File":
            #print("[LOG] Clicked Open File!")
            folder_or_file = sg.popup_get_file('Choose your file')
            # sg.popup("You chose: " + str(folder_or_file))
            #print("[LOG] User chose file: " + str(folder_or_file))
        elif event == 'Submit':
            version = values['-OPTION MENU-']
            if folder_or_file is None or version not in paths:
              #  print("No CSV file selected or wrong Chrome version selected")
                continue
            # Using thread to avoid long time job will block and cause GUI no response
            threading.Thread(target=run_selenium, args=(window, folder_or_file, paths[version])).start()
            # Disable Submit button to prevent submit again when threading
            window['Submit'].update(disabled=True)
          #  print('[LOG] Run Selenium ...')
        elif event == 'Done':
            # Enable Submit button when thread done
            window['Submit'].update(disabled=False)
           # print('[LOG] End Selenium')

    window.close()

main()

通过允许选择 chrome 版本,这将使整个过程变得更加容易,而不是为每个新的 chrome 版本持续重建应用程序

这是 CromeDriver 版本的建议。

from pathlib import Path
from win32com.client import Dispatch

def get_version(file):
    parser = Dispatch("Scripting.FileSystemObject")
    try:
        version = parser.GetFileVersion(file).split(".")[0]
    except Exception:
        version = None
    return version

# It can be read from a json file chromedriver.json for easy update if new version
cromedriver = {
    'explorer': r'C:\Program Files\Google\Chrome\Application\chrome.exe',
    '96': r'.\chromedriver.exe',
    '97': r'.\chromedriver.exe',
    '98': r'.\chromedriver.exe',
}

version = get_version(cromedriver['explorer'])

if version in cromedriver:
    print(Path(cromedriver[version]).absolute())
else:
    print(f'Please download chromedriver.exe for {version} and update chromedriver.json file')