11

Как скачать файл по HTTP?

9

У меня есть небольшая утилита, которую я использую для планового загрузки MP3 файла с веб-сайта. Затем эта утилита создает/обновляет XML файл подкаста, который я добавил в iTunes.

Обработка текста, создающая или обновляющая XML файл, написана на Python. Однако для загрузки самого MP3 файла я использую wget внутри Windows .bat файла. Я бы предпочел, чтобы вся утилита была написана на Python.

Я долго искал способ загрузить файл с помощью Python, именно поэтому вынужден был прибегнуть к использованию wget.

Как мне загрузить файл с помощью Python?

5 ответ(ов)

1

В вашем коде вы используете wb в функции open('test.mp3', 'wb'). Этот параметр открывает файл в бинарном режиме, что означает, что вы можете записывать в файл двоичные данные, такие как аудиофайлы, вместо текстовых данных. Важно использовать бинарный режим, когда вы работаете с файлами, которые не являются текстовыми, например, с MP3-файлами, чтобы избежать искажения данных. Если бы вы открыли файл в текстовом режиме, это могло бы привести к ошибкам или повреждению файла при записи.

В вашем случае, код успешно загружает MP3-файл по указанному URL и сохраняет его локально с именем test.mp3.

0

Ваша функция для скачивания файла по URL выглядит неплохо, и её вполне можно использовать. Вот ваш код с небольшими улучшениями и переводом:

import os
import requests

def download(url):
    get_response = requests.get(url, stream=True)
    
    # Извлекаем имя файла из URL
    file_name = url.split("/")[-1]

    # Сохраняем файл с использованием 'wb' - режим записи в бинарном формате
    with open(file_name, 'wb') as f:
        # Итерируем по содержимому ответа
        for chunk in get_response.iter_content(chunk_size=1024):
            if chunk:  # отфильтровываем пустые фрагменты
                f.write(chunk)

# Пример вызова функции
download("https://example.com/example.jpg")

Объяснение:

  1. Функция download(url) делает запрос к указанному URL.
  2. Мы извлекаем имя файла из URL, используя split("/")[-1].
  3. При помощи with open(file_name, 'wb') as f: открываем файл для записи в бинарном формате, что необходимо для изображения.
  4. Цикл for chunk in get_response.iter_content(chunk_size=1024): позволяет загружать файл порциями по 1024 байта, что также помогает избежать больших затрат памяти при загрузке больших файлов.
  5. Условие if chunk: предотвращает запись пустых фрагментов данных.

Этот подход позволяет более эффективно загружать файлы и обрабатывать их по частям. Убедитесь, что библиотека requests установлена в вашей среде. Вы можете установить её с помощью pip install requests.

0

Вот улучшенная версия кода PabloG для Python 2 и 3:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import (division, absolute_import, print_function, unicode_literals)

import sys
import os
import urllib.request as urllib2 if sys.version_info >= (3,) else __import__('urllib2')
import urllib.parse as urlparse if sys.version_info >= (3,) else __import__('urlparse')

def download_file(url, dest=None):
    """ 
    Скачивает и сохраняет файл по указанному URL в указанную директорию dest.
    """
    u = urllib2.urlopen(url)

    scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
    filename = os.path.basename(path) or 'downloaded.file'
    if dest:
        filename = os.path.join(dest, filename)

    with open(filename, 'wb') as f:
        meta = u.info()
        meta_func = meta.getheaders if hasattr(meta, 'getheaders') else meta.get_all
        meta_length = meta_func("Content-Length")
        file_size = int(meta_length[0]) if meta_length else None
        print("Скачивание: {0} Размер: {1}".format(url, file_size))

        file_size_dl = 0
        block_sz = 8192
        while True:
            buffer = u.read(block_sz)
            if not buffer:
                break

            file_size_dl += len(buffer)
            f.write(buffer)

            status = "{0:16}".format(file_size_dl)
            if file_size:
                status += "   [{0:6.2f}%]".format(file_size_dl * 100 / file_size)
            status += chr(13)
            print(status, end="")
        print()

    return filename

if __name__ == "__main__":  # Запускаем только если файл был вызван напрямую
    print("Тестирование с загрузкой 10МБ")
    url = "http://download.thinkbroadband.com/10MB.zip"
    filename = download_file(url)
    print(filename)

В этом коде исправлены некоторые моменты для повышения читаемости и совместимости между версиями Python 2 и 3. Он также обрабатывает ситуацию, когда имя файла отсутствует, и выводит прогресс загрузки в понятном формате.

0

Ответ на ваш вопрос о совместимости между Python 2 и Python 3 с использованием библиотеки six выглядит следующим образом:

Существует простой, но эффективный способ, который обеспечивает совместимость с обеими версиями Python с помощью библиотеки six. Вы можете использовать следующий код:

from six.moves import urllib
urllib.request.urlretrieve("http://www.example.com/songs/mp3.mp3", "mp3.mp3")

Этот код загружает файл mp3.mp3 с указанного URL и сохраняет его в текущей директории. Использование six.moves позволяет вам писать универсальный код без необходимости беспокоиться о различиях в модулях между Python 2 и Python 3.

0

Следующие методы являются самым распространённым образом для загрузки файлов в Python:

  1. urllib.urlretrieve('url_to_file', file_name)
  2. urllib2.urlopen('url_to_file')
  3. requests.get(url)
  4. wget.download('url', file_name)

Обратите внимание, что urlopen и urlretrieve могут показывать плохую производительность при загрузке больших файлов (размером более 500 МБ). Метод requests.get хранит файл в памяти до завершения загрузки.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь