Search on blog:

Pobieranie plików i zdjęć za pomocą requests

Uwaga: w przykładach wykorzystuje portal httpbin.org, który pozwala na testowanie przesyłania danych między serwerem i klientem.

Dla małych plików i zdjęć, które spokojnie zmieszczą się w pamięci wystarczyć pobranie i zapisanie pliku w całości.

#!/usr/bin/env python

import requests

r = requests.get('http://httpbin.org/image/png')

with open('result.png', 'wb') as f:
    f.write(r.content)

Dla dużych plików należy czytać i zapisywać po kawałku.
Wykorzystuje się do tego stream=True oraz iter_content podając wielkość kawałka do odczytu.

#!/usr/bin/env python

import requests

r = requests.get('http://httpbin.org/image/png', stream=True)

with open('result.png', 'wb') as f:
    for chunk in r.iter_content(chunk_size=1024):
        f.write(chunk)

W wielku przykładach pojawia się jeszcze if który ma sprawdzać czy coś wczytano i nazywane jest to "odfiltrowywaniem sygnałów keep-alive" ale nigdy nie sprawdzałem czy to rzeczywiście jest potrzebne.

#!/usr/bin/env python

import requests

r = requests.get('http://httpbin.org/image/png', stream=True)

with open('result.png', 'wb') as f:
    for chunk in r.iter_content(chunk_size=1024):
        if chunk:
            f.write(chunk)

Być może zastosowanie else pozwoliło by zaobserwować czy if chunk rzeczywiście jest potrzebne.

W innych przyładach stosują przerywanie gdy nic nie dotarło if not chunk co nie musi być równoważne z powyższym przykładem bo w powyższym nawej jeśli nic nie dotarło to nie przerywa się pętli for i można wczytać jakiś następny kawałek (o ile rzeczywiście ma szansę taki kawałek zainstnieć - czego nie sprawdzałem)

#!/usr/bin/env python

import requests

r = requests.get('http://httpbin.org/image/png', stream=True)

with open('result.png', 'wb') as f:
    for chunk in r.iter_content(chunk_size=1024):
        if not chunk:
            break
        f.write(chunk)

W innych przykładach pojawia się też wymuszanie zapisu bufora na do pliku f.flush()) oraz ewentualne wymuszenie systemu na synchronizajce zawartości plików os.fsync().

#!/usr/bin/env python

import requests

r = requests.get('http://httpbin.org/image/png', stream=True)

with open('result.png', 'wb') as f:
    for chunk in r.iter_content(chunk_size=1024):
        if chunk:
            f.write(chunk)
            f.flush()
            os.fsync()
If you like it
Buy a Coffee