python中如何使用requests模塊下載文件並獲取進度提示?

使用python3寫了一個獲取某網站視頻的小程序,下載的時候需要vip帳號登錄。我使用了requests模塊的Session類,但最後下載的時候就要用get方法得到內容,然後通過文件讀寫的方式保存到硬碟;但是我又想實現下載進度的顯示,使用了urllib.request.urlretrieve方法發現由於沒登錄被403了。想請教各位大神,requests庫有沒有辦法能夠下載文件並顯示進度呢?


20160503 修改了代碼縮進,剛玩知乎,當時回答的時候點了插入代碼,貌似沒生效。謝謝 @iliul的修改的格式
------------------------------------------------------------------------------------------------------------
使用Response類的介面iter_content(chunk_size=1)或者iter_lines(chunk_size=512),chunk_size可以設置你指定的大小,指定每次獲取數據的最大值,注意:並不是每次請求回來的content塊都是chunk_size指定的大小。
stream=True是關鍵,這個參數指定響應內容體(response.content)為流。默認為False,在請求時將content一併全部載入;如果調用response.content仍然是全部載入,然後在執行後面的代碼,只是載入時機變成了第一次調用response.content時。如果使用上面的兩個迭代介面調用的話,可以在下載的過程中做一些事情,比如刷新進度條。

資料1:找到了這個迭代介面,不知道怎麼用
資料2:有一個簡單的用法,就是用for循環
ProgressBar一個進度顯示的簡單實現

with closing(requests.get(self.url(), stream=True)) as response:
chunk_size = 1024 # 單次請求最大值
content_size = int(response.headers["content-length"]) # 內容體總大小
progress = ProgressBar(self.file_name(), total=content_size,
unit="KB", chunk_size=chunk_size, run_status="正在下載", fin_status="下載完成")
with open(file_name, "wb") as file:
for data in response.iter_content(chunk_size=chunk_size):
file.write(data)
progress.refresh(count=len(data))

class ProgressBar(object):

def __init__(self, title,
count=0.0,
run_status=None,
fin_status=None,
total=100.0,
unit="", sep="/",
chunk_size=1.0):
super(ProgressBar, self).__init__()
self.info = "【%s】%s %.2f %s %s %.2f %s"
self.title = title
self.total = total
self.count = count
self.chunk_size = chunk_size
self.status = run_status or ""
self.fin_status = fin_status or " " * len(self.statue)
self.unit = unit
self.seq = sep

def __get_info(self):
# 【名稱】狀態 進度 單位 分割線 總數 單位
_info = self.info % (self.title, self.status,
self.count/self.chunk_size, self.unit, self.seq, self.total/self.chunk_size, self.unit)
return _info

def refresh(self, count=1, status=None):
self.count += count
# if status is not None:
self.status = status or self.status
end_str = "
"
if self.count &>= self.total:
end_str = "
"
self.status = status or self.fin_status
print(self.__get_info(), end=end_str)

參考資料:
1. 高級用法 — Requests 1.1.0 文檔
2. Python網路操作大神之requests

博客地址:Python3使用requests模塊顯示下載進度


感謝 @微微寒分享代碼,正好需要!還有你貼代碼怎麼不把格式加上呢QAQ 我改了好半天縮進

#!/usr/bin/env python3

import requests
from contextlib import closing

"""
作者:微微寒
鏈接:https://www.zhihu.com/question/41132103/answer/93438156
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
"""

class ProgressBar(object):
def __init__(self, title, count=0.0, run_status=None, fin_status=None, total=100.0, unit="", sep="/", chunk_size=1.0):
super(ProgressBar, self).__init__()
self.info = "[%s] %s %.2f %s %s %.2f %s"
self.title = title
self.total = total
self.count = count
self.chunk_size = chunk_size
self.status = run_status or ""
self.fin_status = fin_status or " " * len(self.statue)
self.unit = unit
self.seq = sep

def __get_info(self):
# 【名稱】狀態 進度 單位 分割線 總數 單位
_info = self.info % (self.title, self.status, self.count/self.chunk_size, self.unit, self.seq, self.total/self.chunk_size, self.unit)
return _info

def refresh(self, count=1, status=None):
self.count += count
# if status is not None:
self.status = status or self.status
end_str = "
"
if self.count &>= self.total:
end_str = "
"
self.status = status or self.fin_status
print(self.__get_info(), end=end_str)

def main():
with closing(requests.get("http://www.futurecrew.com/skaven/song_files/mp3/razorback.mp3", stream=True)) as response:
chunk_size = 1024
content_size = int(response.headers["content-length"])
progress = ProgressBar("razorback", total=content_size, unit="KB", chunk_size=chunk_size, run_status="正在下載", fin_status="下載完成")
# chunk_size = chunk_size &< content_size and chunk_size or content_size with open("./file.mp3", "wb") as file: for data in response.iter_content(chunk_size=chunk_size): file.write(data) progress.refresh(count=len(data)) if __name__ == "__main__": main()


# -*- coding: utf-8 -*-
"""
@author:songhao
@file: c4.py
@time: 2017/12/19
"""

import os
from urllib.request import urlopen

import requests
from tqdm import tqdm

def download_from_url(url, dst):
"""
@param: url to download file
@param: dst place to put the file
"""
file_size = int(urlopen(url).info().get("Content-Length", -1))

if os.path.exists(dst):
first_byte = os.path.getsize(dst)
else:
first_byte = 0
if first_byte &>= file_size:
return file_size
header = {"Range": "bytes=%s-%s" % (first_byte, file_size)}
pbar = tqdm(
total=file_size, initial=first_byte,
unit="B", unit_scale=True, desc=url.split("/")[-1])
req = requests.get(url, headers=header, stream=True)
with(open(dst, "ab")) as f:
for chunk in req.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
pbar.update(1024)
pbar.close()
return file_size

if __name__ == "__main__":
url = "http://newoss.maiziedu.com/machinelearning/pythonrm/pythonrm5.mp4"
download_from_url(url, "./new.mp4")

原文地址: Python3 使用requests模塊顯示下載視頻並且顯示進度

1.下載續傳

2.顯示進度條


推薦閱讀:

最近在學習Python爬蟲,求大神給點乾貨?
一個網站用兩種或以上的後端編程語言會出現什麼情況?為什麼?
selenium爬蟲被檢測到 該如何破?
Nginx、Gunicorn在伺服器中分別起什麼作用?
Python 如何入門?

TAG:Python | Python3x | 爬蟲計算機網路 | 網頁爬蟲 | requests |