Selenium (Python) - 使用 Chrome 网络驱动程序等待下载过程完成

新手上路,请多包涵

我通过 chromewebdriver (windows) 使用 selenium 和 python 来自动执行从不同页面下载大量文件的任务。我的代码有效,但解决方案远非理想:下面的函数单击网站按钮,启动一个生成 PDF 文件然后下载它的 java 脚本函数。

我不得不使用静态等待以等待下载完成(丑陋)我无法检查文件系统以验证下载何时完成,因为我正在使用多线程(从不同页面下载大量文件一次)并且文件的名称是在网站本身动态生成的。

我的代码:

 def file_download(num, drivervar):
Counter += 1
    try:
        drivervar.get(url[num])
        download_button = WebDriverWait(drivervar, 20).until(EC.element_to_be_clickable((By.ID, 'download button ID')))
        download_button.click()
        time.sleep(10)
    except TimeoutException: # Retry once
        print('Timeout in thread number: ' + str(num) + ', retrying...')
.....

是否可以在 webdriver 中确定下载完成?我想避免使用 time.sleep(x)。

非常感谢。

原文由 BlackMamba 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 693
2 个回答

您可以通过驱动程序访问 chrome://downloads/ 来获取每个下载的状态。

等待所有下载完成并列出所有路径:

 def every_downloads_chrome(driver):
    if not driver.current_url.startswith("chrome://downloads"):
        driver.get("chrome://downloads/")
    return driver.execute_script("""
        var items = document.querySelector('downloads-manager')
            .shadowRoot.getElementById('downloadsList').items;
        if (items.every(e => e.state === "COMPLETE"))
            return items.map(e => e.fileUrl || e.file_url);
        """)

# waits for all the files to be completed and returns the paths
paths = WebDriverWait(driver, 120, 1).until(every_downloads_chrome)
print(paths)

已更新以支持版本 81 之前的更改。

原文由 Florent B. 发布,翻译遵循 CC BY-SA 4.0 许可协议

我遇到了同样的问题并找到了解决方案。您可以检查您的下载文件夹中是否有 .crdownload。如果下载文件夹中有 0 个扩展名为 .crdownload 的文件,则您的所有下载都已完成。我认为这仅适用于铬和铬。

 def downloads_done():
    while True:
        for filename in os.listdir("/downloads"):
            if ".crdownload" in i:
                time.sleep(0.5)
                downloads_done()

每当您调用 downloads_done() 时,它都会自行循环,直到所有下载完成。如果你正在下载像 80 GB 这样的大文件,那么我不推荐这样做,因为这样函数可以达到最大递归深度。

2020年编辑:

 def wait_for_downloads():
    print("Waiting for downloads", end="")
    while any([filename.endswith(".crdownload") for filename in
               os.listdir("/downloads")]):
        time.sleep(2)
        print(".", end="")
    print("done!")

print() 中的“end”关键字参数通常包含换行符,但我们将其替换。虽然 /downloads 文件夹中没有以 .crdownload 结尾的文件名 sleep for 2 seconds and print one dot without newline to console

在发现请求后,我真的不建议再使用 selenium,但是如果它是一个具有 cloudflare 和验证码等的戒备森严的站点,那么您可能不得不求助于 selenium。

原文由 Walter Randomness 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进