كيفية تنزيل ملف كبير في python مع requests.py؟



1 Answers

أسهل بكثير إذا كنت تستخدم Response.raw و shutil.copyfileobj() :

import requests
import shutil

def download_file(url):
    local_filename = url.split('/')[-1]
    r = requests.get(url, stream=True)
    with open(local_filename, 'wb') as f:
        shutil.copyfileobj(r.raw, f)

    return local_filename

هذا دفق الملف إلى القرص دون استخدام الذاكرة الزائدة ، والرمز بسيط.

Question

Requests هي مكتبة جميلة حقا. أود استخدامه لتنزيل ملفات كبيرة (> 1GB). المشكلة أنه ليس من الممكن الاحتفاظ بملف كامل في الذاكرة أحتاج لقراءته في قطع. وهذه مشكلة في التعليمة البرمجية التالية

import requests

def DownloadFile(url)
    local_filename = url.split('/')[-1]
    r = requests.get(url)
    f = open(local_filename, 'wb')
    for chunk in r.iter_content(chunk_size=512 * 1024): 
        if chunk: # filter out keep-alive new chunks
            f.write(chunk)
    f.close()
    return 

لسبب ما لا يعمل بهذه الطريقة. لا يزال يحمّل الاستجابة في الذاكرة قبل حفظها في ملف.




ليس بالضبط ما كان يسأل OP ، ولكن ... من السخرية للغاية القيام بذلك مع urllib :

from urllib.request import urlretrieve
url = 'http://mirror.pnl.gov/releases/16.04.2/ubuntu-16.04.2-desktop-amd64.iso'
dst = 'ubuntu-16.04.2-desktop-amd64.iso'
urlretrieve(url, dst)

أو بهذه الطريقة ، إذا كنت تريد حفظها في ملف مؤقت:

from urllib.request import urlopen
from shutil import copyfileobj
from tempfile import NamedTemporaryFile
url = 'http://mirror.pnl.gov/releases/16.04.2/ubuntu-16.04.2-desktop-amd64.iso'
with urlopen(url) as fsrc, NamedTemporaryFile(delete=False) as fdst:
    copyfileobj(fsrc, fdst)

لقد شاهدت العملية:

watch 'ps -p 18647 -o pid,ppid,pmem,rsz,vsz,comm,args; ls -al *.iso'

ورأيت الملف ينمو ، ولكن بقي استخدام الذاكرة في 17 ميغابايت. هل فاتني شيء؟






Related