使用 Selenium 填充表单时使用 openpyxl 读取 Excel 文件花费的时间太长

Reading Excel File with openpyxl while populating form using Selenium takes too long

我正在填写一个网络表单,其中包含输入字段、下拉菜单、自动完成字段和操作按钮。

我正在使用 openpyxl 从 excel sheet 中提取数据。最初,填充这些字段需要 3-4 秒。将 read_only=True 添加到我的 readData 函数后,它有所改善,但没有达到预期。

有没有人对我如何能够减少填充每个字段所需的时间有任何建议?非常感谢任何帮助。我将保留 readData 函数以及用于填写文本字段的 populate_form 作为示例。

干杯。

读取每个单元格的方法:

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")

尝试使用 'xlrd' 库实现 readData 方法。

它不像 openpyxl 那样提供丰富的 API,但我相信它会 运行 更快。

除非你的点差sheet 很大,否则我相当确定 wait_for_elementWebDriverWait 调用花费的时间最多。
正如已经建议的那样,尝试使用高效结构缓存 spreadsheet(s) 数据,例如:

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:[=20 访问加载的数据=]

#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]

如果 sheet 名称 无效或 IndexError 无效 行,以上将抛出 KeyError,列组合。

当您填写网络表单时,最终数据将通过 POST 请求发送到服务器。 我推荐的是使用例如wireshark 捕获 POST 请求。 分析该请求以查看发送到服务器的确切内容。然后,您可以使用 requests 模块 创建 这样的 POST 请求。 这意味着您根本不必处理硒。

正如其他人所提到的,只阅读 excel 文件一次。