Чтение файла Excel с openpyxl при заполнении формы с помощью Selenium занимает слишком много времени - PullRequest
0 голосов
/ 17 апреля 2020

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

Я извлекаю данные из таблицы Excel, используя openpyxl. Изначально заполнение этих полей занимало 3-4 секунды. После добавления read_only=True к моей функции readData она немного улучшилась, но не так, как ожидалось.

Есть ли у кого-нибудь какие-либо предложения о том, как я смогу сократить время, необходимое для заполнения каждого поля? Любая помощь очень ценится. Я оставляю как функцию readData, так и функцию populate_form, которую я использую для заполнения текстового поля в качестве примера.

Cheers.

Метод чтения каждой ячейки:

workbook = openpyxl.load_workbook(file, read_only=True)

def readData(file, sheetName, row_num, column_num):
    sheet = workbook.get_sheet_by_name(sheetName)
    return sheet.cell(row=row_num, column=column_num).value

Способ заполнения поля ввода:

def fill_out_form(driver, path, input_sel, row_num, column_num):
    try:
        wait_for_element(driver, "//input[@id='" + input_sel + "']", 5)
        xls = readData(path, "Callcenter", row_num, column_num)
        input_el = driver.find_element_by_xpath("//input[@id='" + input_sel + "']")
        input_el.click()
        if column_num == 9 or column_num == 40 or column_num == 67 or column_num == 121:
            xls = datetime.strftime(xls,'%d/%m/%Y')
        input_el.send_keys(xls)
        input_el.send_keys(Keys.TAB)
        loading_el = WebDriverWait(driver, 4).until(EC.presence_of_element_located((By.XPATH, "//*[@class='sk-attr js-sk-attr sk-attr--labeled sk-attr--mandatory sk-attr--infonnized sk-attr--error sk-textbox clearfix']")))
        WebDriverWait(driver, 4).until(wait_not_spinning(loading_el))
    except TimeoutException:
        print("Loading took too much time!-Try again")

Ответы [ 3 ]

1 голос
/ 18 апреля 2020

Если ваша электронная таблица не очень большая, я вполне уверен, что вызовы wait_for_element и WebDriverWait занимают больше всего времени.
Как уже было предложено, попробуйте кэшировать данные электронной таблицы, используя эффективную структуру, такую ​​как :

dict[file][sheet] = list[row][column]

Поскольку кажется, что у вас есть только один файл, вы можете загрузить данные, используя:

def load_data(filename):
    data = {}
    workbook = openpyxl.load_workbook(filename, data_only=True, read_only=True, keep_vba=False)
    for sheet_name in workbook.sheetnames:
        data[sheet_name] = []
        sheet = workbook[sheet_name]
        for rows in sheet.iter_rows():
            row_elements = []
            for cell in rows:
                try:
                    value = cell.value
                except IndexError:
                    value = cell.internal_value
                row_elements.append(value)
            data[sheet_name].append(row_elements)
    return data

Чтобы использовать его, вы должны вызвать load_data(filename) один раз (когда ваш приложение запускается), а затем получить доступ к загруженным данным, используя xls_data вместо readData:

#application start
xls_data = load_data(filename)

....
# sheet_name->str, row_num->int, col_num->int
xls = xls_data[sheet_name][row_num][col_num]

Выше будет выброшено KeyError, если имя листа недопустимо или IndexError для недопустимой строки, столбца комбинации.

1 голос
/ 18 апреля 2020

Когда вы заполните веб-форму, в конце данные будут отправлены на сервер с запросом POST. Я бы порекомендовал использовать, например, wireshark для capture того POST-запроса. Проанализируйте этот запрос, чтобы увидеть, что именно отправляется на сервер. Затем вы можете создать такой запрос POST, используя модуль requests. Это означает, что вам вообще не нужно иметь дело с селеном.

И, как уже упоминалось, прочитайте файл Excel только один раз.

1 голос
/ 18 апреля 2020

Попробуйте реализовать метод readData с помощью библиотеки 'xlrd'.

Он не предоставляет богатый API, такой как openpyxl, но я уверен, что он будет работать быстрее.

...