函数代码如下:
import os, urllib,request, threading, posixpath, urllib.parse, atexit, random
pool_sema = threading.BoundedSemaphore(value=6) #max number of download threads #设置多线程的线程数
socket.setdefaulttimeout(5000) #设置超时
in_progress = [] #定义一个空list供存储进行的download任务
def download(url):
pool_sema.acquire() #开启线程池
path = urllib.parse.urlsplit(url).path #解析url,去掉http://....(即第一个'/'前面的内容) 如http://www.baidu.com/tf/boys.jpg的结果为'/tf/boys.jpg'
filename = posixpath.basename(path) #取path字符串最后一个'/'后面的字符串作为名称 如'/tf/boys.jpg'的结果为'boys.jpg'
while os.path.exists(outputpath + '/' + filename):
filename = str(random.randint(0, 100)) + filename #如果检查到目标文件夹中已经有此下载内容,则对要下载的文件重命名,前面加上0-100间的随机数
in_progress.appen(filename) #将要下载的任务加入list
try:
urllib.request.urlretrieve(url, output_path + '/' + filename) #下载url对应的文件
in_progress.remove(filename) #下载成功从list中划掉此任务
except:
print("----------------- Download failed: " + filename) #提示用户此文件下载失败
pool_sema.release() #释放线程池
def removeNotFinished(): #此函数用于程序关闭时的回调函数
for filename in in_progress:
try:
os.remove(output_path + '/' + filename) #删除没有完成的任务
except FileNotFoundError:
pass
关于程序关闭时的回调函数:atexit.register(removeNotFinished)
定义了一个register函数用于注册程序退出时的回调函数,可以在这个回调函数中做一些资源清理的操作。如果程序是非正常的crash或者通过os._exit()退出,注册的回调函数将不会被调用。