[英]How to limit download speed in python3 requests?
我正在使用請求在運行 Linux 的小型嵌入式設備上下載一個大(~50MiB)文件。
文件將寫入附加的 MMC。
不幸的是,MMC 寫入速度低於凈速度,我看到 memory 消耗增加,在某些情況下,我什至遇到 kernel “無法處理頁面......”錯誤。
設備只有 128MiB RAM。
我正在使用的代碼是:
with requests.get(URL, stream=True) as r:
if r.status_code != 200:
log.error(f'??? download returned {r.status_code}')
return -(offset + r.status_code)
siz = 0
with open(sfn, 'wb') as fo:
for chunk in r.iter_content(chunk_size=4096):
fo.write(chunk)
siz += len(chunk)
return siz
寫入 MMC 時如何暫時停止服務器?
if r.status_code != 200:
log.error(f'??? download returned {r.status_code}')
return -(offset + r.status_code)
siz = 0
with open(sfn, 'wb') as fo:
for chunk in r.iter_content(chunk_size=4096):
fo.write(chunk)
siz += len(chunk)
return siz
您可以將其重寫為協程
import requests
def producer(URL,temp_data,n):
with requests.get(URL, stream=True) as r:
if r.status_code != 200:
log.error(f'??? download returned {r.status_code}')
return -(offset + r.status_code)
for chunk in r.iter_content(chunk_size=n):
temp_data.append(chunk)
yield #waiting to finish the consumer
def consumer(temp_data,fname):
with open(fname, 'wb') as fo:
while True:
while len(temp_data) > 0:
for data in temp_data:
fo.write(data)
temp_data.remove(data) # To remove it from the list
# You can add sleep here
yield #waiting for more data
def coordinator(URL,fname,n=4096):
temp_data = list()
c = consumer(temp_data,fname)
p = producer(URL,temp_data,n)
while True:
try:
#getting data
next(p)
except StopIteration:
break
finally:
#writing data
next(c)
這些都是您需要的功能。 調用這個
URL = "URL"
fname = 'filename'
coordinator(URL,fname)
如果 web 服務器支持http Range
字段,您可以請求僅下載大文件的一部分,然后逐步瀏覽整個文件。
看看這個問題,James Mills 給出了以下示例代碼:
from requests import get
url = "http://download.thinkbroadband.com/5MB.zip"
headers = {"Range": "bytes=0-100"} # first 100 bytes
r = get(url, headers=headers)
由於您的問題是 memory,因此您需要阻止服務器一次向您發送整個文件,因為這肯定會被您設備上的某些代碼緩沖。 除非您可以讓請求刪除它收到的部分數據,否則這將始終是個問題。 requests
下游的額外緩沖區將無濟於事。
您可以嘗試使用此 bash 命令減小 TCP 接收緩沖區的大小:
echo 'net.core.rmem_max=1000000' >> /etc/sysctl.conf
(1 MB,你可以調整這個)
這將阻止在該過程的這個階段建立巨大的緩沖區。
然后編寫代碼僅從 TCP 堆棧讀取並以指定的時間間隔寫入 MMC 以防止緩沖區在系統的其他地方建立,例如 MMC 寫緩沖區 - 例如@e3n 的答案。
希望這會導致數據包被丟棄,然后在緩沖區再次打開時由服務器重新發送。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.