Как многократно повторять множество наборов данных и вводить данные в метод? (ткинтер, селен python) - PullRequest
0 голосов
/ 18 марта 2020

Я пытаюсь написать программу автоматизации, которая будет принимать вводимые пользователем данные из единственного пользовательского интерфейса и автоматически вводить эти данные на один веб-сайт или несколько веб-сайтов.

UI

Когда нажата кнопка «Получить цитату», открывается сеанс браузера chrome и помещает все данные из пользовательского интерфейса в соответствующую запись поля на сайте.

browsersessionexample

Сейчас я пытаюсь выяснить, как учитывать ситуации, когда существует более 1 набора данных. Например:

UIexample2

Вот изображение того, что я хочу, чтобы программа могла делать. В основном введите второй набор данных и нажмите «Добавить элемент строки», и если для ввода не осталось данных, скрипт автоматически щелкнет «Создать смарт-предложение».

websessionexamplescenario

Каков наилучший подход к возможности ввода второго или третьего набора данных? Данные должны быть повторно введены тем же способом. Вот некоторый код для контекста.

from tkinter import *
from tkinter import font
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select 

orders = {}
def order_data():
    # start by adding a dict to the dict with key of length dict,
    # the first key will be 0, then 1, 2 and so on
    orders[len(orders)] = {}

    # next you can start adding data using len - 1 to access the correct key
    # and so on for all your data
    orders[len(orders) - 1]['handling unit'] = e3.get()
    orders[len(orders) - 1]['pieces'] = e4.get()
    orders[len(orders) - 1]['description'] = e5.get()
    orders[len(orders) - 1]['length'] = e6.get()
    orders[len(orders) - 1]['width'] = e7.get()
    orders[len(orders) - 1]['height'] = e8.get()
    orders[len(orders) - 1]['weight'] = e9.get()
    orders[len(orders) - 1]['classification'] = e10.get()    


def GetQuote():

    origin_zip = int(e1.get()) #gets entries stores data here
    destination_zip = int(e2.get())
    handling_unit = [e3.get()]
    pieces = [e4.get()]
    description = [e5.get()]
    length = [e6.get()]
    width = [e7.get()]
    height = [e8.get()]
    weight = [e9.get()]
    classification_list =[e10.get]

    driver = webdriver.Chrome("/home/***/***/chromedriver")

    driver.maximize_window() #driver.set_window_size(10, 10)

    #1st Tab (shipco.com)
    driver.get("https://tms.shipco.com/Main/Home")
    driver.implicitly_wait(1)

    #1st Tab Login Page
    driver.find_element(By.XPATH, "//button[@id='dropdownMenuButton']").click()
    driver.find_element(By.XPATH, "//input[@id='UserName']").send_keys('***')
    driver.find_element(By.XPATH, "//input[@id='Password']").send_keys('***')
    driver.find_element(By.XPATH, "//button[@class='btn btn-primary btn-block']").click()

    #1st Tab 2nd Page
    driver.find_element(By.XPATH, "//input[@id='OriginZip']").send_keys(origin_zip)
    driver.find_element(By.XPATH, "//input[@id='DestinationZip']").send_keys(destination_zip)
    driver.find_element(By.XPATH, "//button[@class='btn btn-secondary form-control']").click()

    #Will have to add a conditional statement here to iterate through instances of multiple items/dimensions/weights

    #1st Tab 3rd Page
    driver.refresh();
    for i in range(len(orders)):
        driver.find_element(By.ID, "handlingunits").send_keys(orders[i]['handling unit'])
        driver.find_element(By.ID, "quantityofgoods").send_keys(orders[i]['pieces'])
        driver.find_element(By.ID, "commoditydescription").send_keys(orders[i]['description'])
        driver.find_element(By.ID, "sizelength").send_keys(orders[i]['length'])
        driver.find_element(By.ID, "sizewidth").send_keys(orders[i]['width'])
        driver.find_element(By.ID, "sizeheight").send_keys(orders[i]['height'])
        driver.find_element(By.ID, "totalweight").send_keys(orders[i]['weight'])

        driver.implicitly_wait(10)
        driver.find_element(By.XPATH, "//a[@class='ng-binding']").click()      #this will click the object that gets class for shipment
        if i < len(orders):
            driver.find_element(By.XPATH, "//button[@class='btn btn-info']").click() 

    driver.find_element(By.XPATH, "//span[contains(text(),'Generate Smart Quote')]").click()     

def insert_into_textbox(): #generates input fields for the next set of items

    order_data()   
    #get the inputs
    handling_unit = e3.get()
    pieces = e4.get()
    description = e5.get()
    length = e6.get()
    width = e7.get()
    height = e8.get()
    weight = e9.get()
    classification = e10.get()

    textbox_display = (handling_unit.ljust(11)+pieces.ljust(13)+description.ljust(11)+length.ljust(10)+width.ljust(11)+height.ljust(11)+weight.ljust(10)+classification+"\n")

    textbox.insert("end",textbox_display)
    e3.delete(0, "end")
    e4.delete(0, "end")
    e5.delete(0, "end")
    e6.delete(0, "end")
    e7.delete(0, "end")
    e8.delete(0, "end")
    e9.delete(0, "end")
    e10.delete(0, "end")


master = Tk() 
master.title("Quote Automator")
master.configure(background="#eef56e")
arial8 = font.Font(family="Arial", size=8, weight=font.BOLD)
algerian8 = font.Font(family="Algerian", size=8, weight=font.BOLD)

e1 = Entry(master, borderwidth=5, width=12) #origin zip
e2 = Entry(master, borderwidth=5, width=12) #destination zip
e3 = Entry(master, borderwidth=5, width=12) #handling unit(s)
e4 = Entry(master, borderwidth=5, width=12) #piece(s)
e5 = Entry(master, borderwidth=5, width=13) #description(s)
e6 = Entry(master, borderwidth=5, width=12) #length(s)
e7 = Entry(master, borderwidth=5, width=12) #width(s)
e8 = Entry(master, borderwidth=5, width=12) #height(s)
e9 = Entry(master, borderwidth=5, width=12) #weight(s)
e10 = Entry(master, borderwidth=5, width=12) #class(s)

# grid method customizes position
e1.grid(row = 0, column = 2, pady = 1, sticky="W")  #origin zip
e2.grid(row = 0, column = 4, pady = 1, sticky="W") #destination zip
e3.grid(row = 3, column = 1, pady = 1, sticky="W") #handling unit(s)
e4.grid(row = 3, column = 2, pady = 1, sticky="W") #piece(s)
e5.grid(row = 3, column = 3, pady = 1, sticky="W")  #description(s)
e6.grid(row = 3, column = 4, pady = 1, sticky="W")  #length(s)
e7.grid(row = 3, column = 5, pady = 1, sticky="W") #width(s)
e8.grid(row = 3, column = 6, pady = 1, sticky="W") #height(s)
e9.grid(row = 3, column = 7, pady = 1, sticky="W") #weight(s)
e10.grid(row = 3, column = 8, pady = 1, sticky="W") #class(s)

textbox=Text(master, width=9, borderwidth=5, height=7)
textbox.grid(row=5, column=1, columnspan=9, sticky="nsew")

scrollbar=Scrollbar(master, orient="vertical", command=textbox.yview)
scrollbar.grid(row=5, column=10, sticky=NS)
textbox.configure(yscrollcommand=scrollbar.set)


b0 = Button(master, text = "Add Set", bg="white", fg="black", font=arial8, command=insert_into_textbox) #Add Next Set Button
b1 = Button(master, text = "Caculate Class", bg="yellow", font=arial8, command=set_class)
b2 = Button(master, text = "Get Quote", bg="#6fff00", fg="#7170ff", font=arial8, width=10, command=GetQuote) 

b0.grid(row = 3, column = 0, sticky = W) # Add Next Set Button Positioning
b1.grid(row = 0, column = 8, sticky = E) # Calculate Class Button Positioning
b2.grid(row = 0, column = 7, sticky = E) # Get Quote Button Positioning

mainloop() 

pic5 enter image description here

1 Ответ

1 голос
/ 18 марта 2020

Вы можете сделать что-то вроде добавления каждой строки в словарь, где каждый ключ является числом. Тогда каждое значение может быть другим словарем или именованным кортежем. Затем вы можете l oop с помощью цифровых клавиш в вашем методе получить значения для каждой строки.

Например, используя dict, вы можете сделать функцию для приема данных.

orders = {}
    def order_data():
        # start by adding a dict to the dict with key of length dict,
        # the first key will be 0, then 1, 2 and so on
        orders[len(orders)] = {}

        # next you can start adding data using len - 1 to access the correct key
        orders[len(orders) - 1]['handling unit'] = e3.get()
        # and so on for all your data

Затем, когда вы вызываете свой метод, вы можете использовать для l oop для ввода данных для каждой строки.

for i in range(len(orders)):
    class.method(i)

Затем внутри вашего метода для каждой функции send_keys вы можете вызвать словарь

driver.find_element(By.ID, "handlingunits").send_keys(orders[i]['handling unit'])

Вы также можете сделать для l oop внутри метода, если хотите,

for i in range(len(orders)):
        driver.find_element(By.ID, "handlingunits").send_keys(orders[i]['handling unit'])
        driver.find_element(By.ID, "quantityofgoods").send_keys(orders[i]['pieces'])
        driver.find_element(By.ID, "commoditydescription").send_keys(orders[i]['description'])
        driver.find_element(By.ID, "sizelength").send_keys(orders[i]['length'])
        driver.find_element(By.ID, "sizewidth").send_keys(orders[i]['width'])
        driver.find_element(By.ID, "sizeheight").send_keys(orders[i]['height'])
        driver.find_element(By.ID, "totalweight").send_keys(orders[i]['weight'])

        driver.implicitly_wait(10)
        driver.find_element(By.XPATH, "//a[@class='ng-binding']").click()      #this will click the object that gets class for shipment
        if i < len(orders):
            driver.find_element(By.XPATH, "//button[@class='btn btn-info']").click() #add another line of items if avaiable
    driver.find_element(By.XPATH, "//span[contains(text(),'Generate Smart Quote')]").click()

Поместить часть 'add new line' внутри l oop с помощью logi c, как это заставит программу продолжать добавлять, пока данные не будут израсходованы, и затем она нажмет кнопку «Сгенерировать Smart Quote».

...