小能豆

Python Selenium 单击而不是选项卡即可打开新窗口

py

我尝试在身份验证后使用 python selenium 下载一些文件,但当 selenium 单击文件链接时,它会打开一个新窗口,因此它会再次要求身份验证。我可以使用相同的身份验证强制 selenium 下载文件而不打开新窗口或在新选项卡中下载文件吗?

elementList = driver.find_elements_by_class_name("file-link")
for el in elementList:
    el.click()

更新 1:

elementList = driver.find_elements_by_class_name("file-link")
for el in elementList:
    driver.execute_script("arguments[0].setAttribute('target', 'self')", el)
    el.click()

但仍然有多个窗口。


阅读 24

收藏
2025-01-02

共1个答案

小能豆

在使用 Selenium 下载文件时,如果链接触发新窗口或新标签页打开,你遇到的身份验证问题可能是由于 Selenium 无法在新的标签页中保持相同的会话。为了避免这种情况,您可以尝试以下几种方法:

1. 强制在当前窗口中打开链接(通过设置 target="_self"

你已经尝试通过执行 JavaScript 来将链接的 target 属性设置为 _self,这通常是防止新标签页打开的方法。然而,若仍然存在多个窗口问题,可以检查以下内容:

  • 确保 driver.switch_to.window() 没有被意外切换到新窗口。
  • 确保 target='_self' 被正确应用于所有链接。

这里是一个更新的代码示例:

elementList = driver.find_elements_by_class_name("file-link")
for el in elementList:
    driver.execute_script("arguments[0].setAttribute('target', '_self')", el)  # 强制在当前窗口中打开
    el.click()

2. 使用 WebDriverWaitdriver.switch_to.window() 控制新窗口切换

如果仍然遇到打开新窗口的问题,您可以在每次点击链接后使用 driver.switch_to.window() 来手动切换窗口,并确保返回到原始窗口。您可以利用 window_handles 来获取所有窗口句柄:

original_window = driver.current_window_handle  # 获取当前窗口的句柄
elementList = driver.find_elements_by_class_name("file-link")

for el in elementList:
    el.click()
    WebDriverWait(driver, 10).until(EC.new_window_is_opened(driver.window_handles))  # 等待新窗口打开
    new_window = [window for window in driver.window_handles if window != original_window][0]  # 获取新窗口句柄
    driver.switch_to.window(new_window)  # 切换到新窗口
    # 这里执行文件下载操作
    # 例如,检查文件是否下载完成,或者下载的链接的URL
    driver.close()  # 关闭新窗口
    driver.switch_to.window(original_window)  # 切回原始窗口

3. 使用 Selenium 的浏览器设置防止新窗口打开

在某些浏览器中,您可以通过设置来防止打开新窗口。例如,在使用 Chrome 时,可以禁用所有弹出窗口:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--disable-popup-blocking")  # 禁用弹出窗口拦截
driver = webdriver.Chrome(options=chrome_options)

4. 使用 requestswget 进行文件下载

如果文件下载链接非常直接且无需与页面交互,那么您可以考虑使用 requests 库或 wget 来直接下载文件。这样就无需通过 Selenium 来打开文件链接,从而避免了多个窗口的干扰。

例如,使用 requests 来下载文件:

import requests

file_url = "https://example.com/file"
response = requests.get(file_url, cookies=driver.get_cookies())  # 传递会话cookie以保持身份验证
with open("downloaded_file", "wb") as f:
    f.write(response.content)

通过这种方法,你可以绕过 Selenium,直接下载文件,同时保持会话的有效性。

总结:

如果你希望避免多窗口的问题,可以通过以下几种方式:
- 强制设置 target="_self" 来保证文件链接在当前窗口中打开。
- 使用 driver.switch_to.window() 来控制窗口切换,避免打开新的标签页。
- 通过修改浏览器设置来禁用弹窗。
- 如果可能,使用 requestswget 直接下载文件。

你可以根据需求选择适合的方法。

2025-01-02