在使用python3下载图片时, 常用的方法有urlretrieve和requests两种, 不管哪种方法在网速极慢的情况下, 会出现图片下载卡住现象。那如何解决呢? 小编根据网上提供的资料测试了几种方法。
1、socket: 设置默认超时
正常下载的情况
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __author__:kzg import datetime import os from urllib.request import urlretrieve # 函数运行计时器 def count_time(func): def int_time(*args, **kwargs): start_time = datetime.datetime.now() # 程序开始时间 func(*args, **kwargs) over_time = datetime.datetime.now() # 程序结束时间 total_time = (over_time-start_time).total_seconds() print("download picture used time %s seconds" % total_time) return int_time # 下载回调函数, 计算下载进度 def callbackinfo(down, block, size): ''' 回调函数: down:已经下载的数据块 block:数据块的大小 size:远程文件的大小 ''' per = 100.0 * (down * block) / size if per > 100: per = 100 print('%.2f%%' % per) # 图片下载 @count_time def downpic(url, filename): try: print("Start Down %s" % url) if os.path.exists(filename): os.remove(filename) urlretrieve(url, filename, callbackinfo) except socket.timeout as ex: print(ex) url = "http://p1.meituan.net/wedding/d4c375416ab70b8b0bc4247875c929b0434138.jpg%40800w_600h_0e_1l%7Cwatermark%3D1%26%26r%3D1%26p%3D9%26x%3D2%26y%3D2%26relative%3D1%26o%3D20" filename = r'C:\blueprint-face-detection\scripts\mv.jpg' downpic(url, filename) 结果: Start Down http://p1.meituan.net/wedding/d4c375416ab70b8b0bc4247875c929b0434138.jpg%40800w_600h_0e_1l%7Cwatermark%3D1%26%26r%3D1%26p%3D9%26x%3D2%26y%3D2%26relative%3D1%26o%3D20 0.00% 7.01% 14.02% 21.03% 28.04% 35.05% 42.06% 49.07% 56.08% 63.09% 70.10% 77.11% 84.12% 91.13% 98.14% 100.00% download picture used time 0.165558 seconds
结论: 网速较快时下载完全没问题, 仅用零点几秒。
2、使用charles限制网速, 设置为下载1k/s, 上传10k/s
1、设置charles
2、设置socket的默认超时时间为10秒
#!/usr/bin/env python3# -*- coding:utf-8 -*-# __author__:kzgimport datetimeimport osimport socketfrom urllib.request import urlretrieve# 函数运行计时器def count_time(func): def int_time(*args, **kwargs): start_time = datetime.datetime.now() # 程序开始时间 func(*args, **kwargs) over_time = datetime.datetime.now() # 程序结束时间 total_time = (over_time-start_time).total_seconds() print("download picture used time %s seconds" % total_time) return int_time# 下载回调函数, 计算下载进度def callbackinfo(down, block, size): ''' 回调函数: down:已经下载的数据块 block:数据块的大小 size:远程文件的大小 ''' per = 100.0 * (down * block) / size if per > 100: per = 100 print('%.2f%%' % per)# 图片下载@count_timedef downpic(url, filename): try: print("Start Down %s" % url) if os.path.exists(filename): os.remove(filename) urlretrieve(url, filename, callbackinfo) except socket.timeout as ex: print(ex)url = "http://p1.meituan.net/wedding/d4c375416ab70b8b0bc4247875c929b0434138.jpg%40800w_600h_0e_1l%7Cwatermark%3D1%26%26r%3D1%26p%3D9%26x%3D2%26y%3D2%26relative%3D1%26o%3D20"filename = r'C:\blueprint-face-detection\scripts\mv.jpg'# 设置10秒超时socket.setdefaulttimeout(10)downpic(url, filename)
结果: Start Down http://p1.meituan.net/wedding/d4c375416ab70b8b0bc4247875c929b0434138.jpg%40800w_600h_0e_1l%7Cwatermark%3D1%26%26r%3D1%26p%3D9%26x%3D2%26y%3D2%26relative%3D1%26o%3D20 timed out download picture used time 10.013625 seconds
结论: 正如期望的那样, 10秒种后下载自动结束了,重试了3次, 每次都好使, 好高兴 ^_^
猜想, 那我把网速提高一些呢, 应该更好使吧!!!, 下载10k/s, 上传10k/s。
完啦, 擦擦擦, 这是什么情况, 网速提高了, 下载好久了还没结束。
经过多次尝试发现下载设置超过4k/s时, socket设置defaulttime就不起作用了。
待叙……