Python 3.5 - Selenium - 如何处理新窗口并等待它完全加载?

时间:2017-01-10 14:27:55

标签: python selenium selenium-webdriver browser webdriver

我正在进行浏览器自动化,我在某个时刻被阻止:我立刻要求浏览器点击一个按钮,然后打开一个新窗口。但有时互联网太慢,所以这个新窗口需要时间来加载。我想知道如何让Selenium等到这个新的新窗口完全加载。

这是我的代码:

driver.switch_to.default_content()
Button = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, 'addPicturesBtn')))
Button.click()
newWindow = driver.window_handles
time.sleep(5)
newNewWindow = newWindow[1]
driver.switch_to.window(newNewWindow)
newButtonToLoad = driver.find_element_by_id('d')
newButtonToLoad.send_keys('pic.jpg')
uploadButton = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, 'uploadPics')))
uploadButton.click()
driver.switch_to.window(newWindow[0])

我不时会收到此错误:

  

newNewWindow = newWindow [1]

     

IndexError:列表索引超出范围

这让我觉得一个简单的“时间睡眠”(5)'不做这项工作。

所以,我的问题是,我怎么能等到这个新窗口完全加载才能与之交互?

感谢

2 个答案:

答案 0 :(得分:4)

您可以尝试使用以下代码等到新窗口出现:

WebDriverWait(driver, 20).until(EC.number_of_windows_to_be(2))

您的代码应该是

Button.click()

WebDriverWait(driver, 20).until(EC.number_of_windows_to_be(2))

newWindow = driver.window_handles
newNewWindow = newWindow[1]
driver.switch_to.window(newNewWindow)

考虑@JimEvans评论,请尝试以下内容:

current = driver.window_handles[0]
Button.click()

WebDriverWait(driver, 20).until(EC.number_of_windows_to_be(2))

newWindow = [window for window in driver.window_handles if window != current][0]
driver.switch_to.window(newWindow)

答案 1 :(得分:0)

我正在使用什么:

windows = set(driver.window_handles)
driver.execute_script("window.open()")
WebDriverWait(driver, 20).until(EC.new_window_is_opened(windows))
hwnd = list(set(driver.window_handles) - windows)[0]

如果发现必要,可以为其创建函数或上下文管理器like this answer,但实际上需要3行(不包括实际打开窗口的那一行,每种情况可能会有所不同) ,我更喜欢只复制粘贴。

更详尽地说,这是功能丰富的替代方案:

@contextmanager
def wait_for_new_window(driver, timeout=10, switch=True):
    """Waits for a new window to open

    Parameters:
        driver: WebDriver.
            Selenium WebDriver object.
        timeout: int
            Maximum waiting time
        switch: bool
            If `True` (default), switches to the window.


    Exemplo:
        >>> with wait_for_new_window(driver) as hwnds:
        ...     driver.execute_script("window.open()");
        ... print("Window opened:", hwnds[0])
    """
    windows = set(driver.window_handles)
    handle = []
    yield handle
    WebDriverWait(driver, timeout).until(EC.new_window_is_opened(windows))
    hwnds = list(set(driver.window_handles) - windows)
    handle.extend(hwnds)
    if switch:
        driver.switch_to.window(hwnds[0])