Загрузка файлов через requests: практические примеры

Раздел: Сетевое программирование -> HTTP-запросы

Библиотека requests позволяет легко загружать файлы из сети. В зависимости от размера файла и требований к производительности выбирается подходящий способ.

Методы загрузки файлов через requests

Как эффективно скачать большой файл, не загружая его целиком в память?

Основное решение использует потоковую передачу данных. Параметр stream=True в запросе GET позволяет получать ответ по частям. Метод iter_content() возвращает итератор по кускам данных указанного размера.

import requests

url = 'https://example.com/large_file.zip'
response = requests.get(url, stream=True)
response.raise_for_status()

with open('large_file.zip', 'wb') as f:
    for chunk in response.iter_content(chunk_size=8192):
        if chunk:
            f.write(chunk)

запрос страницы python (запрос веб-страницы в python)

Такой подход экономит оперативную память, так как файл не сохраняется целиком в переменную.

Как скачать небольшой файл одним вызовом?

Можно получить содержимое ответа целиком атрибутом content:

import requests

response = requests.get('https://example.com/small.txt')
with open('small.txt', 'wb') as f:
    f.write(response.content)

Python requests (библиотека requests в python)

Ограничение: этот способ загружает весь файл в память, поэтому для больших объёмов (сотни мегабайт) не рекомендуется.

Как добавить проверку успешности запроса?

Метод raise_for_status() выбрасывает исключение при кодах 4xx или 5xx. Это защищает от записи ошибочного содержимого.

response = requests.get(url)
response.raise_for_status()
with open('file', 'wb') as f:
    f.write(response.content)

Python request download (скачивание файла через requests)

Если не проверять статус, можно сохранить страницу с ошибкой вместо файла. Рекомендуется всегда вызывать raise_for_status().

Как передать заголовки, например User-Agent?

Аргумент headers принимает словарь с заголовками. Это полезно для имитации браузера или аутентификации.

headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(url, headers=headers, stream=True)
Некоторые серверы блокируют запросы без заголовка User-Agent. Добавление корректного заголовка решает проблему.

Как передать параметры запроса?

Для GET-запросов с параметрами (например, токен или идентификатор) используется аргумент params.

params = {'token': 'abc123', 'format': 'pdf'}
response = requests.get(url, params=params)

Типичные ошибки и их решение

  • MemoryError: возникает при скачивании больших файлов без stream=True. Решение: использовать потоковую загрузку.
  • ConnectionError: сервер недоступен. Рекомендуется обернуть вызов в блок try-except и реализовать повторные попытки.
  • Timeout: сервер не отвечает в течение заданного времени. Параметр timeout помогает избежать зависания.
  • HTTPError (4xx/5xx): обрабатывается с помощью raise_for_status() или проверки response.status_code.
  • Проблемы с именем файла: сервер может не предоставлять заголовок Content-Disposition. Для сохранения можно извлекать имя из URL.

Расширенные примеры скачивания файлов

Ниже представлены более сложные сценарии использования requests для загрузки файлов.

Пример 1: Скачивание с отображением прогресса с помощью tqdm

Библиотека tqdm позволяет показать индикатор выполнения. Необходимо установить её (pip install tqdm).

Пример
import requests
from tqdm import tqdm

url = 'https://example.com/large_file.zip'
response = requests.get(url, stream=True)
response.raise_for_status()

total_size = int(response.headers.get('content-length', 0))
block_size = 8192

with open('large_file.zip', 'wb') as f:
    with tqdm(total=total_size, unit='B', unit_scale=True, desc='Downloading') as pbar:
        for chunk in response.iter_content(chunk_size=block_size):
            if chunk:
                f.write(chunk)
                pbar.update(len(chunk))
Downloading: 100%|██████████| 100M/100M [00:10<00:00, 9.5MB/s]

Пример 2: Скачивание с повторными попытками при ошибках

Модуль urllib3 или requests.adapters позволяет настроить повторные попытки.

Пример
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
import requests

session = requests.Session()
retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[500, 502, 503, 504],
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount('http://', adapter)
session.mount('https://', adapter)

response = session.get('https://example.com/vulnerable_file.pdf', stream=True)
response.raise_for_status()
with open('file.pdf', 'wb') as f:
    for chunk in response.iter_content(8192):
        f.write(chunk)
Файл успешно загружен после 2 повторных попыток.

Пример 3: Скачивание с использованием сессии и куков

Для сайтов, требующих авторизации, можно использовать объект Session для сохранения куков.

Пример
with requests.Session() as s:
    # Авторизация
    s.post('https://example.com/login', data={'user': 'user1', 'pass': 'secret'})
    # Загрузка защищённого файла
    r = s.get('https://example.com/protected/file.doc', stream=True)
    r.raise_for_status()
    with open('file.doc', 'wb') as f:
        for chunk in r.iter_content(8192):
            f.write(chunk)
Файл file.doc загружен с сохранёнными куками.

Скачивание файла через requests - comments

En
Python request download (python)