什么是使用urllib3下载文件的最佳方式
问题描述:
我想用urllib3
通过HTTP
协议下载文件。 我已成功地做到这一点使用下面的代码:什么是使用urllib3下载文件的最佳方式
url = 'http://url_to_a_file'
connection_pool = urllib3.PoolManager()
resp = connection_pool.request('GET',url)
f = open(filename, 'wb')
f.write(resp.data)
f.close()
resp.release_conn()
但我想知道什么是这样做的适当方式。 例如,它可以很好地处理大文件,并且如果没有该做什么来使这些代码更具有容错性和可扩展性。
注意。例如,使用urllib3
库不是urllib2
对我来说很重要,因为我希望我的代码是线程安全的。
答
您的代码片段已关闭。值得一提的有两两件事:
如果您使用
resp.data
,它会消耗整个响应并返回连接(你没有需要手动resp.release_conn()
)。如果你把数据保存在内存中很酷,这很好。您可以使用
resp.read(amt)
这将传输响应,但连接将需要通过resp.release_conn()
返回。
这看起来是这样的......
import urllib3
http = urllib3.PoolManager()
r = http.request('GET', url, preload_content=False)
with open(path, 'wb') as out:
while True:
data = r.read(chunk_size)
if not data:
break
out.write(data)
r.release_conn()
该文档可能会有点欠缺这种方案。如果有人有兴趣制作pull-request to improve the urllib3 documentation,那将不胜感激。命名变量:)
答
最正确的方式做到这一点可能是获取表示HTTP响应一个类似文件的对象,并将其复制使用shutil.copyfileobj到一个真实的文件如下:
url = 'http://url_to_a_file'
c = urllib3.PoolManager()
with c.request('GET',url, preload_content=False) as resp, open(filename, 'wb') as out_file:
shutil.copyfileobj(resp, out_file)
resp.release_conn() # not 100% sure this is required though
那么。谢谢你的回答。 –
还有一个问题。如果我添加'r = http.request('POST',url)'',它会与POST方法一起工作吗? –
@ running.t错误,这是我的代码中的错误。你是对的,该方法应该先行,你的代码段将起作用。 (更新了我的答案。) – shazow