python selenium,找到下载完成后?

时间:2015-12-17 15:57:38

标签: python selenium

我使用了selenium来启动下载。下载完成后,需要采取某些措施,是否有任何简单的方法可以找出下载完成的时间? (我正在使用FireFox驱动程序)

11 个答案:

答案 0 :(得分:15)

没有内置的selenium方式等待下载完成。

这里的一般想法是等到文件出现在“下载”目录中

这可能是通过一遍又一遍地检查文件存在来实现的:

或者,通过使用watchdog之类的东西来监控目录:

答案 1 :(得分:6)

我最近遇到了这个问题。我一次下载了多个文件,如果下载失败,我必须以一种超时的方式进行构建。

该代码每秒检查一些下载目录中的文件名,并在文件名完成或退出时间超过20秒后退出。返回的下载时间用于检查下载是否成功或超时。

import time
import os

def download_wait(path_to_downloads):
    seconds = 0
    dl_wait = True
    while dl_wait and seconds < 20:
        time.sleep(1)
        dl_wait = False
        for fname in os.listdir(path_to_downloads):
            if fname.endswith('.crdownload'):
                dl_wait = True
        seconds += 1
    return seconds

我认为这仅适用于以.crdownload扩展名结尾的chrome文件。可能有类似的方法可以签入其他浏览器。

编辑:最近我更改了在.crdownload未显示为扩展名的情况下使用此功能的方式。本质上,这也只是等待正确数量的文件。

def download_wait(directory, timeout, nfiles=None):
    """
    Wait for downloads to finish with a specified timeout.

    Args
    ----
    directory : str
        The path to the folder where the files will be downloaded.
    timeout : int
        How many seconds to wait until timing out.
    nfiles : int, defaults to None
        If provided, also wait for the expected number of files.

    """
    seconds = 0
    dl_wait = True
    while dl_wait and seconds < timeout:
        time.sleep(1)
        dl_wait = False
        files = os.listdir(directory)
        if nfiles and len(files) != nfiles:
            dl_wait = True

        for fname in directory:
            if fname.endswith('.crdownload'):
                dl_wait = True

        seconds += 1
    return seconds

答案 2 :(得分:4)

import os
import time

def latest_download_file():
      path = r'Downloads folder file path'
      os.chdir(path)
      files = sorted(os.listdir(os.getcwd()), key=os.path.getmtime)
      newest = files[-1]

      return newest

fileends = "crdownload"
while "crdownload" == fileends:
    time.sleep(1)
    newest_file = latest_download_file()
    if "crdownload" in newest_file:
        fileends = "crdownload"
    else:
        fileends = "none"

这是一些解决方案的组合。我不喜欢这样,我必须扫描整个下载文件夹以找到以“ crdownload”结尾的文件。该代码实现了将下载文件夹中的最新文件拉出的功能。然后,它仅检查该文件是否仍在下载中。将它用于我正在构建的Selenium工具中效果很好。

答案 3 :(得分:2)

我想回答这个问题为时已晚,尽管想为以后的读者分享一个hack。

您可以从主线程创建一个名为 thread1 的线程,然后在此处启动下载。 现在,创建另一个线程,例如 thread2 ,在其中,等待它直到使用join()方法完成 thread1 为止。现在,您可以在执行之后继续执行流程下载完成。

仍然请确保您不使用硒启动下载,而是使用硒提取链接并使用请求模块进行下载。

Download using requests module

例如:

def downloadit():
     #download code here    

def after_dwn():
     dwn_thread.join()           #waits till thread1 has completed executing
     #next chunk of code after download, goes here

dwn_thread = threading.Thread(target=downloadit)
dwn_thread.start()

metadata_thread = threading.Thread(target=after_dwn)
metadata_thread.start()

答案 4 :(得分:2)

在下载目录中的文件名中检查“未确认”关键字:

# wait for download complete
wait = True
while(wait==True):
    for fname in os.listdir('\path\to\download directory'):
        if ('Unconfirmed') in fname:
            print('downloading files ...')
            time.sleep(10)
        else:
            wait=False
print('finished downloading all files ...')

文件下载完成后,它退出while循环。

答案 5 :(得分:1)

如果使用 Selenium 和 Chrome,您可以编写自定义等待条件,例如:

class file_has_been_downloaded(object):
def __init__(self, dir, number):
    self.dir = dir
    self.number = number

def __call__(self, driver):
    print(count_files(dir), '->', self.number)
    return count_files(dir) > self.number

count_files 函数只是验证文件是否已添加到文件夹

def count_files(direct):
for root, dirs, files in os.walk(direct):
    return len(list(f for f in files if f.startswith('MyPrefix') and (
            not f.endswith('.crdownload')) ))

然后在您的代码中实现这一点:

files = count_files(dir)
<< copy the file. Possibly use shutil >>
WebDriverWait(driver, 30).until(file_has_been_downloaded(dir, files))

答案 6 :(得分:0)

使用Chrome时,尚未完成下载的文件的扩展名为.crdownload。如果您set your download directory正确,那么您可以等到您想要的文件不再具有此扩展名。原则上,这与等待文件存在(如suggested by alecxe)没有太大区别 - 但至少你可以用这种方式监视进度。

答案 7 :(得分:0)

x1=0
while x1==0:
    count=0
    li = os.listdir("directorypath")
    for x1 in li:
        if x1.endswith(".crdownload"):
             count = count+1        
    if count==0:
        x1=1
    else:
        x1=0

如果您要检查一组文件(多个)是否已完成下载,则此方法有效。

答案 8 :(得分:0)

如前所述,没有原生方法可以检查下载是否完成。因此,这里有一个帮助程序功能,适用于Firefox和Chrome。一种技巧是在开始新下载之前清除临时下载文件夹。另外,请使用本机pathlib进行跨平台使用。

from pathlib import Path

def is_download_finished(temp_folder):
    firefox_temp_file = sorted(Path(temp_folder).glob('*.part'))
    chrome_temp_file = sorted(Path(temp_folder).glob('*.crdownload'))
    downloaded_files = sorted(Path(temp_folder).glob('*.*'))
    if (len(firefox_temp_file) == 0) and \
       (len(chrome_temp_file) == 0) and \
       (len(downloaded_files) >= 1):
        return True
    else:
        return False

答案 9 :(得分:0)

这对我有用:

fileends = "crdownload"
while "crdownload" in fileends:
    sleep(1)
    for fname in os.listdir(some_path): 
        print(fname)
        if "crdownload" in fname:
            fileends = "crdownload"
        else:
            fileends = "None"

答案 10 :(得分:0)

虽然我有更好的选择:

因此,重定向开始下载的功能。例如download_function = lambda:element.click()

检查目录中的文件数,然后等待没有下载扩展名的新文件。之后,将其重命名。 (可以更改为移动文件,而不是在同一目录中重命名)

def save_download(self, directory, download_function, new_name, timeout=30):
    """
    Download a file and rename it
    :param directory: download location that is set
    :param download_function: function to start download
    :param new_name: the name that the new download gets
    :param timeout: number of seconds to wait for download
    :return: path to downloaded file
    """
    self.logger.info("Downloading " + new_name)
    files_start = os.listdir(directory)
    download_function()
    wait = True
    i = 0
    while (wait or len(os.listdir(directory)) == len(files_start)) and i < timeout * 2:
        sleep(0.5)
        wait = False
        for file_name in os.listdir(directory):
            if file_name.endswith('.crdownload'):
                wait = True
    if i == timeout * 2:
        self.logger.warning("Documents not downloaded")
        raise TimeoutError("File not downloaded")
    else:
        self.logger.info("Downloading done")
        new_file = [name for name in os.listdir(directory) if name not in files_start][0]
        self.logger.info("New file found renaming " + new_file + " to " + new_name)
        while not os.access(directory + r"\\" + new_file, os.W_OK):
            sleep(0.5)
            self.logger.info("Waiting for write permission")
        os.rename(directory + "\\" + new_file, directory + "\\" + new_name)
        return directory + "\\" + new_file