前言
日常很多下载器不能满足需要,很多码农都想自己写代码从头下载,但是有时候会遇到要下载的文件非常大,导致内存装不下,经常出现下载失败的状况,白白耗了半天时间,非常让人头疼。当遇到这种问题,那只能是get一部分数据就往磁盘写,每次保证内存中只有小量级数据即可。
Python下载文件的方法有两种:
1. Python官方的urlib库
2. Python第三方包requests
这两个库各有优劣,以前很多人都建议使用urlib,但是却没人说的出啥理由,现在很多人慢慢喜欢了requests库,主要是requests库非常简洁,更高层,上手快,单requests库对一些需要ssl认证的却有些问题。
下面具体讲解使用urlib和requests库下载大文件的方法:
使用requests库下载大文件
当使用requests的get下载大文件/数据时,建议使用使用stream模式。
当把get函数的stream参数设置成False时,它会立即开始下载文件并放到内存中,如果文件过大,有可能导致内存不足。
当把get函数的stream参数设置成True时,它不会立即开始下载,当你使用iter_content或iter_lines遍历内容或访问内容属性时才开始下载。需要注意一点:文件没有下载之前,它也需要保持连接。
iter_content:一块一块的遍历要下载的内容
iter_lines:一行一行的遍历要下载的内容
使用上面两个函数下载大文件可以防止占用过多的内存,因为每次只下载小部分数据。
示例代码:
r = requests.get(url_file, stream=True)
f = open("file_path", "wb")
# chunk是指定每次写入的大小,每次只写了512byte
for chunk in r.iter_content(chunk_size=512):
if chunk:
f.write(chunk)
使用urlib库下载大文件
使用urlib下载大文件和小文件都差不多,只不过在read()函数中指定了每次读入文件的大小,这种方法不能像上面那样使用迭代器,只能使用for循环,还得判断最后文件是否读完。
示例代码:
from urllib.request import Request, urlopen
from urllib.error import HTTPError, URLError
req = Request(link)
# 增加header头信息
req.add_header('User-Agent',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36')
try:
chunk_size=512
response = urlopen(req)
while True:
#在read()中指定读入块的大小
tmp = response.read(chunk_size)
if not tmp:
break
response.close()
with open(file_name, 'wb') as f:
f.write(tmp)