首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Selenium (Python) -使用Chrome web驱动程序等待下载过程完成

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

Stack Overflow用户
提问于 2018-01-15 20:45:34
回答 9查看 25.7K关注 0票数 18

我通过chromewebdriver (windows)使用selenium和python,以便自动化从不同页面下载大量文件的任务。我的代码可以工作,但解决方案远非理想:下面的功能点击网站按钮,启动一个java脚本功能,生成PDF文件,然后下载它。

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

我的代码:

代码语言:javascript
复制
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)。

非常感谢。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2018-01-16 01:22:17

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

要等待所有下载完成并列出所有路径,请执行以下操作:

代码语言:javascript
复制
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之前的更改。

票数 48
EN

Stack Overflow用户

发布于 2018-07-29 05:50:43

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

代码语言:javascript
复制
def downloads_done():
    while True:
        for filename in os.listdir("/downloads"):
            if ".crdownload" in i:
                time.sleep(0.5)
                downloads_done()

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

2020编辑:

代码语言:javascript
复制
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休眠2秒结束,并且在控制台中打印一个不带换行符的圆点

我真的不再推荐在发现请求之后使用selenium,但如果它是一个非常严密保护的站点,使用cloudflare和captchas等,那么您可能不得不求助于selenium。

票数 8
EN

Stack Overflow用户

发布于 2020-03-14 05:18:17

使用Chrome 80时,我必须通过以下代码将答案从@florent b更改为:

代码语言:javascript
复制
def every_downloads_chrome(driver):
    if not driver.current_url.startswith("chrome://downloads"):
        driver.get("chrome://downloads/")
    return driver.execute_script("""
        return document.querySelector('downloads-manager')
        .shadowRoot.querySelector('#downloadsList')
        .items.filter(e => e.state === 'COMPLETE')
        .map(e => e.filePath || e.file_path || e.fileUrl || e.file_url);
        """)

我相信这是复古兼容的,我的意思是这应该适用于老版本的Chrome。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48263317

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档