首页 > 解决方案 > 来自非唯一 id 的 Python Selenium 下载文件

问题描述

希望有人会对如何做到这一点有所了解。

我刚开始使用 Selenium,并且有一个非常具体的任务要执行。我将一种格式的文件上传到免费的在线服务,该服务将其转换为另一种格式,并将我重定向到可以下载转换后文件的页面,但我必须单击按钮或链接才能做到这一点。(作为记录,我不能使用转换器来执行此操作,因为服务会将信息添加到文件中,而不仅仅是转换文件类型)

问题是包含转换后文件的页面的 URL 是通用的(例如https://www.something.com/convert?output),当我尝试让 Selenium 在那里搜索文件时,它只是转到没有输出的通用链接,而不是停留在重定向文件的页面。

我知道有一个选项可以让驱动程序等待页面加载然后继续执行任务,但据我所知,它仍然需要一个新的 URL,最终结果是一样的。

有谁知道如何做到这一点?

这是我当前的代码:

from selenium import webdriver

options = webdriver.ChromeOptions()

preferences = {"download.default_directory": "/home/marko/files"}

options.add_experimental_option("prefs", preferences)

driver = webdriver.Chrome('/home/marko/Downloads/chromedriver', chrome_options=options)

driver.get("url of the converting site")

choose_file = driver.find_element_by_name('uploaded_file_1')

file_location = "/home/marko/file.original"

choose_file.send_keys(file_location)

get_data = driver.find_element_by_xpath("//input[@value='Convert & add']").click()

driver.get("https://www.something.com/convert?output") -> here's the trouble

driver.find_element_by_partial_link_text("following link").click()

标签: pythonselenium

解决方案


只需让网络将您重定向到带有链接或下载按钮的页面。

您需要做的是让浏览器等待。为此,您可以使用:

  • 隐式等待( driver.implicitly_wait(seconds)):这会在您每次搜索项目时添加等待。当机器或连接速度很慢时特别有用。
  • 显式等待(带WaitWebDriver()):等待某个条件直到某个超时时间。当您等待一个长时间的进程时特别有用,该进程的时间与页面加载的其余部分无关。

因此,使用显式等待,代码将如下所示:

from selenium import webdriver
# New imports
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

options = webdriver.ChromeOptions()

preferences = {"download.default_directory": "/home/marko/files"}

options.add_experimental_option("prefs", preferences)

driver = webdriver.Chrome('/home/marko/Downloads/chromedriver', chrome_options=options)

driver.get("url of the converting site")

choose_file = driver.find_element_by_name('uploaded_file_1')

file_location = "/home/marko/file.original"

choose_file.send_keys(file_location)

get_data = driver.find_element_by_xpath("//input[@value='Convert & add']").click()

# Once the process is started, wait for the element to be clickable
wait = WebDriverWait(driver, 20) # Adjust the timeout seconds to a reasonable max time for the process
element = wait.until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, 'following link')))

element.click()

您可以在此处了解更多信息并找到更多等待条件。


推荐阅读