问题提出
在某些场合,可能需要判断一个网页的图片最大能下载到哪一个位置,在采用多线程的方式去下载。
例如一个网页有一堆图片,图片的链接有一定的规律性,例如
http://kd.nsfc.gov.cn/report/19/19331042_1.png
http://kd.nsfc.gov.cn/report/19/19331042_2.png
一般方法是寻找到图片能下载的最大位置,借用request方法来判断图片是否能下载:
image = "http://kd.nsfc.gov.cn/report/19/19331042_{}.png"
max = 0
for i in range(1, 1000):
if request(image.format(i), headers=headers).status == 200:
max = i # 修改最大位置
这样做不仅效率低,而且有时候会访问出错,甚至一个网页要花好几秒才能返回状态码。
通过我的观察,我发现:urlretrieve
方法,它能有一个极快的速度来进行判断。
当某个图片的链接无法下载的时候,返回404异常
或是其他(根据网站判断)
于是便可写成下列代码:
try:
#image_url: 图片链接
#save_file: 保存位置
max = 0
for i in range(1, 1000):
image = "http://kd.nsfc.gov.cn/report/19/19331042_{}.png"
urlretrieve(image_url.format(i), save_file) # 如果无法下载,则抛出异常404
except Except as e:
try:
if(str(e).index("404")):
max = index # 修改max的大小
except Except as e:
print(e)
这样做便可大大提高寻找 “最大能下载图片的位置
” 的效率。
当然如果结合二分算法,会更快:
# approval_num: 用于构造下载链接的批准号
# local_image: 保存图片的位置
# min, max : 查找的上限下限
def BinarySearchIndex(approval_num, local_image , min, max):
while True:
index = min + int((max - min) / 2) # 中间值
print(min, index, max)
try:
image_url = "http://kd.nsfc.gov.cn/report/{}/{}_{}.png".format(approval_num[0:2], approval_num, index)
urlretrieve(image_url, local_image)
if min == index:
return min
min = index
except Exception as e :
print(e)
try:
if (str(e).index("404") > 0):
max = index
except Exception as e:
print(e)