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