【问题标题】:How to switch window handles using Selenium and Python如何使用 Selenium 和 Python 切换窗口句柄
【发布时间】:2019-12-25 07:21:14
【问题描述】:

如果您单击 Web 浏览器以外的 Windows 程序中的链接,则会出现一个弹出窗口。我想获取这个弹出窗口的 url。弹窗只会在 IE 中打开。

driver = webdriver.Ie('C://Users/aaa/IEDriverServer.exe')
driver.implicitly_wait(3)
pyautogui.moveTo(1576, 660)
pyautogui.click()
time.sleep(3)
driver.switch_to_window(driver.window_handles[1])
   # error =>driver.switch_to_window(driver.window_handles[1])
   #         IndexError: list index out of range
driver.get_window_position(driver.window_handles[1])

windows = driver.window_handles
   # Commenting out the above two lines will result in only one active web 
   # browser in windows.
print(windows)

driver = webdriver.Ie('C://Users/seula/IEDriverServer.exe')
driver.implicitly_wait(3)
pyautogui.moveTo(1576, 660)
pyautogui.click()
time.sleep(3)
driver.switch_to_window(driver.window_handles[1])
   # error =>driver.switch_to_window(driver.window_handles[1])
   #         IndexError: list index out of range
driver.get_window_position(driver.window_handles[1])

windows = driver.window_handles
   # Commenting out the above two lines will result in only one active web 
   # browser in windows.
print(windows)

在此源中,运行 IEDriver.exe 会打开一个 localhost 窗口,并在您使用 pyautogui 单击 Windows 程序的链接时弹出。 但是,如果我检查 driver.window_handles,则只显示 localhost 窗口并且无法识别弹出窗口。如何获取弹窗网址?

【问题讨论】:

    标签: python selenium selenium-webdriver webdriverwait window-handles


    【解决方案1】:

    正如西蒙在讨论中明确提到的那样:

    虽然用于存储句柄列表的数据类型可以按插入排序,但 WebDriver 实现迭代窗口句柄以插入它们的顺序不需要稳定。顺序是任意的。

    所以你必须:

    • number_of_windows_to_be(2) 引入 WebDriverWait
    • 由于窗口的顺序是随机的,因此您可以在执行交互之前获取窗口句柄集合,并将其与执行操作后的集合进行比较。
    • 您可以使用以下解决方案:

      driver = webdriver.Ie('C://Users/aaa/IEDriverServer.exe')
      driver.implicitly_wait(3)
      windows_before  = browser.current_window_handle
      pyautogui.moveTo(1576, 660)
      pyautogui.click()
      WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))
      windows_after = driver.window_handles
      new_window = [x for x in windows_after if x != windows_before][0]
      driver.switch_to.window(new_window)
      

    参考:您可以在以下位置找到一些相关讨论:

    【讨论】:

      【解决方案2】:

      我通常使用 send_keys() 而不是 click() 来处理弹出窗口。

      尝试使用以下代码:

      pyautogui.send_keys(Keys.CONTROL + Keys.ENTER)
      driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + "2")
      # window_handles[-1] refer to last window created.
      driver.switch_to.window(self.driver.window_handles[-1])
      url = driver.current_url
      print(url)
      

      【讨论】:

        【解决方案3】:

        要获取当前网址,您可以使用:

        windows = driver.current_url
        print(windows)
        

        【讨论】:

        • driver.window_handles [1] 中出现错误。 IndexError: 列表索引超出范围。 . .可以识别 driver.window_handles [1] 丢失。
        • 这里错driver.window_handles[1],检查正确的窗口名称,并切换。这表示当前只有一个窗口。