Python requests 分段下載文件


requests分段下載文件

默認情況下,requests當你進行網絡請求后,響應體會立即被下載,當數據過大時會導致內存不足。

這時候可以通過 stream 參數來設置請求數據。

當在請求上設置stream=True時,這避免了立即將內容讀入內存以獲得較大的響應。推遲下載響應體直到訪問 Response.content 屬性。

如果stream=False(默認),數據將作為單個塊返回。

示例:

url = 'https://www.baidu.com/'
r = requests.get(url, stream=True)

此時僅有 響應頭 被下載下來了,連接保持打開狀態。直到訪問 Response.content

content = r.content

此時才能獲取到數據。

注意:

如果你在請求中把 stream 設為 True,Requests 無法將連接釋放回連接池,除非你 消耗了所有的數據,或者調用了 Response.close。 這樣會帶來連接效率低下的問題。如果你發現你在使用 stream=True 的同時還在部分讀取請求的 body(或者完全沒有讀取 body),那么你就應該考慮使用 with 語句發送請求,這樣可以保證請求一定會被關閉:

示例:

with requests.get(url, stream=True) as r:
    content = r.content

 

這個時候也沒有解決問題。

如何一段段的請求數據呢?

1、流式請求

流式請求就是像流水一樣,不是一次過來而是一點一點“流”過來。處理流式數據也是一點一點處理。

可以使用 Response.iter_lines() 或 Response.iter_content()

iter_content(chunk_size = 1 , decode_unicode = False)

迭代響應數據。這避免了立即將內容讀入內存以獲得較大的響應。chunk_size是它應該讀入內存的字節數。chunk_size的類型必須是intNoneNone的值將根據流的值發揮不同的作用。

iter_lines(chunk_size=512decode_unicode=Nonedelimiter=None)

遍歷響應數據,一次一行。

這兩個都要設置 steam=True 才能使用

import requests
url = 'https://www.baidu.com/'
r = requests.get(url, stream=True)
# iter_lines
# 一行一行的讀取數據
for line in r.iter_lines():
    if line:
        decoded_line = line.decode('utf-8')
        print('line:', decoded_line)

 

 

# iter_content,指定每次讀取大小
for chunk in r.iter_content(chunk_size=20):
     if chunk:
            decoded_chunk = chunk.decode('utf-8')
            print(decoed_chunk)

 

2、自己設置請求位置

當設置steam=True,沒有訪問 Response.content時,只是得到了請求頭。

在請求頭里有一個參數:content-Length,可以獲取文件長度。

當有content-Length時,就可以在請求頭里設置每次請求位置。這要用到: Range 字段

沒有content-Length不能使用

# 設置請求視頻開始:start和結束:end的位置
headers = {
    'Range': f'bytes={start}-{end}',
}
r = requests.get(url, headers=headers)

 

參考鏈接:

https://blog.csdn.net/m0_46652894/article/details/106018558

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM