如何创建for循环以避免Selenium错误

时间:2019-02-08 06:21:25

标签: python selenium

我正在使用Selenium来自动执行任务。

手动任务需要某人发送批量发票。 有两个部分:

  1. 排队等待打印的发票
  2. 排队等待发送电子邮件的发票

Sectio 2(排队等待发送电子邮件的发票)可以批量发送,但第1节(排队等待打印传递的发票)需要通过单击“电子邮件”按钮单独发送。

在第1部分中单击此电子邮件按钮后,将出现一个弹出窗口,并且需要单击“发送发票”按钮,然后在发送发票后将关闭弹出窗口。

第1节并非始终出现。因此,当第1部分没有电子邮件时,该部分不可见。此部分的电子邮件数量也有所不同。

我以前遇到过 StaleElementReferenceException 错误,并设法通过获取主页的新元素来避免该错误。

我现在遇到的问题是,如果第1节有5封电子邮件,我无法弄清楚应该在脚本中执行循环的方式或位置,以便在弹出窗口中单击“发送发票”窗口并返回主窗口,获取新鲜元素并返回弹出窗口...

这是我的代码:

### Do email run - Invoices Queued for Email Delivery ###

# Select the last table (Email delivery) and find the first checkbox and click 
tables = driver.find_elements_by_class_name('fsmall')
tables[-1].find_element_by_css_selector("td:nth-child(1)").click()

# Click Do email run button
driver.find_element_by_name("email_queue").click()

# Wait for 50 seconds
time.sleep(50)

# Get page again once DOM loaded
driver.get(url)

# Find Invoices Queued for Print Delivery Section
tables = driver.find_elements_by_class_name('fsmall')

if 'Invoices Queued for Print Delivery' in [item.text for item in tables]:

    ### First loop
    # Get table index of print delivery section 
    print_delivery_ind = [item.text for item in tables].index('Invoices Queued for Print Delivery')

    # Get the table after Print Delivery table
    idvdl_inv_tbl = tables[print_delivery_ind + 1]

    # Get name of main window
    main_window = driver.window_handles[0]

    # Find the first invoice and click Email
    idvdl_inv_tbl.find_element_by_link_text('Email').click()

    # Wait for 3 seconds
    time.sleep(3)

    # Get name of the pop up window
    popup_window = driver.window_handles[1]

    # Switch to the pop up window
    driver.switch_to_window(popup_window)

    # Find the Send Invoice button and click
    driver.find_element_by_name("submit_email").click()

    # Switch to the main window
    driver.switch_to_window(main_window)

    ### Second loop
    # Get page again once DOM loaded
    driver.get(url)

    # Get all tables
    tables = driver.find_elements_by_class_name('fsmall')

    # Get table index of Print Delivery section 
    print_delivery_ind = [item.text for item in tables].index('Invoices Queued for Print Delivery')

    # Get the table after Print Delivery table
    idvdl_inv_tbl = tables[print_delivery_ind + 1]

    # Get name of main window
    main_window = driver.window_handles[0]

    # Find the first invoice and click Email
    idvdl_inv_tbl.find_element_by_link_text('Email').click()

    # Wait for 3 seconds
    time.sleep(3)

    # Get name of the pop up window
    popup_window = driver.window_handles[1]

    # Switch to the pop up window
    driver.switch_to_window(popup_window)

    # Find the Send Invoice button and click
    driver.find_element_by_name("submit_email").click()

driver.close()

如果有人能指出我正确的方向,将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:1)

只要表中有“排队等待打印交付的发票”,那么会有一个令人惊讶的小变化,它将使您的循环重复进行。更改此行:

if 'Invoices Queued for Print Delivery' in [item.text for item in tables]:

收件人:

while 'Invoices Queued for Print Delivery' in [item.text for item in tables]:

然后在循环体内删除第二个元素聚集-同时保持页面重新加载和tables的重新初始化。因此,这些行:

### First loop
# Get table index of print delivery section 
print_delivery_ind = [item.text for item in tables].index('Invoices Queued for Print Delivery')

# -----
# the rest of the lines 
# -----

# up until these - keep them, and nothing afterwards:
# Get page again once DOM loaded
driver.get(url)

# Get all tables
tables = driver.find_elements_by_class_name('fsmall')

因此,当页面上有带有该文本的表格时,您将循环浏览。