# 先进行一些必要操作
  from selenium import webdriver
  driver_path = r"D:chromedriverchromedriver.exe"
  # 我使用的是Chrome浏览器
  driver = webdriver.Chrome(executable_path=driver_path)

官方文档

If your site opens a new tab or window, Selenium will let you work with it using a window handle. Each window has a unique identifier which remains persistent in a single session.

也就是说handle就像id一样用来区分各页面或窗口,因此可以对比彼此页面的句柄(handle)来确定目前WebDriver的focus在何处。(句柄的顺序和标签页顺序一致)

页面创建

点击页面内的链接

    # 打开百度
    driver.get("https://www.baidu.com")
    # 打印出handle
    print(driver.current_window_handle) #  ['CDwindow-054B40A910BFCD2D1E20DABB1272A62B']
    # 点击页面里面的新闻链接 
    driver.find_element_by_name("tj_trnews").click()
    # 打印handle
    print(driver.current_window_handle) #  ['CDwindow-054B40A910BFCD2D1E20DABB1272A62B']

没有新建窗口,只是在原始页面打开,所以只有一个句柄并且相同,当然,点击target="_blank"的链接,是会在新的标签页打开页面的,并且将会有两个句柄,但是当前所在窗口句柄仍然相同

使用JS

    # 打开百度
    driver.get("https://www.baidu.com")
    # 打印出handle
    print(driver.window_handles) # ['CDwindow-560A9B54BF935A8249566C795D6D857D']
    print(driver.current_window_handle) # CDwindow-560A9B54BF935A8249566C795D6D857D
    # 打开新页面
    driver.execute_script('window.open("http://news.baidu.com/")') # 直接在新的标签页打开了此页面
    # 打印出handle
    print(driver.window_handles) # ['CDwindow-560A9B54BF935A8249566C795D6D857D', 'CDwindow-108E4B9171C6D7FA4CCAAAF4FEACCAFE']
    print(driver.current_window_handle) # CDwindow-560A9B54BF935A8249566C795D6D857D

打开了新的标签页,所以之后有两个句柄,但是可以看到,两次输出当前句柄都是同一个,所以focus并没有变化,依然是原始的标签页

官方文档

Clicking a link which opens in a new window will focus the new window or tab on screen, but WebDriver will not know which window the Operating System considers active.

WebDriver 并不知道目前哪个窗口目前是处于活动状态。
首先可以确认一点,句柄不变,那么对driver进行操作只会影响到原始页面,因此当需要对新的页面的(非原始[not the original])进行操作时,是需要进行切换的。

页面切换

为了可以操作新页面对象,页面之间的切换是必不可少的

方法一
window_handle会返回一个列表,包含了当window对象所有的标签页,并且顺序与此列表一致。因此可以直接使用列表索引进行切换。

driver.get("https://www.baidu.com")
print(driver.current_window_handles) # CDwindow-BF39F0A6A262522BA4A72EA1B9244D65
driver.execute_script('window.open("http://news.baidu.com/")')
print(driver.current_window_handles) # CDwindow-BF39F0A6A262522BA4A72EA1B9244D65
print("*" * 30) # *号隔开加以区分
driver.switch_to.window(driver.window_handles[1])
print(driver.current_window_handle) # CDwindow-34D81646E7A6EED9E8528EAEE5E8D117

可以看出switch_to.window()后句柄就不一致了,说明focus已经切换到新打开的窗口了,此后就可以对新页面进行操作了。需要切换到原始页面,再一次执行switch_to.window()就行,注意句柄应该是0索引
 
方法二(官方)

# Loop through until we find a new window handle
for window_handle in driver.window_handles:
    if window_handle != original_window:
        driver.switch_to.window(window_handle)
        break

关闭close

当不再需要新的页面后我们就将其关闭,driver.close()即可,关闭后,window_handle也就少了一个句柄。

需要注意的是,关闭一个页面后,一定要记得切换到其他有效窗口句柄,怎样切换就不说了。另外,页面(句柄)关闭后,在进行切换之前,是不能再对已关闭的页面进行任何操作的,即使是print(current_window_handle)这样的操作也不可以。

目前python最新版本是selenium 3.141.0,也就是说selenium 4版本中的创建新页面后自动进行切换是没有的,需要注意。