Скачать файл из сети в Python 3 - PullRequest
266 голосов
/ 30 августа 2011

Я создаю программу, которая загружает файл .jar (java) с веб-сервера, считывая URL-адрес, указанный в файле .jad той же игры / приложения.Я использую Python 3.2.1

Мне удалось извлечь URL файла JAR из файла JAD (каждый файл JAD содержит URL-адрес файла JAR), но, как вы можете себе представить,извлеченное значение - строка типа ().

Вот соответствующая функция:

def downloadFile(URL=None):
    import httplib2
    h = httplib2.Http(".cache")
    resp, content = h.request(URL, "GET")
    return content

downloadFile(URL_from_file)

Однако я всегда получаю сообщение о том, что тип в функции выше должен быть байтами, а не строкой.Я пытался использовать URL.encode ('utf-8'), а также байты (URL, encoding = 'utf-8'), но всегда получал ту же или похожую ошибку.

Поэтому в основном мой вопрос заключается в том, как загрузить файл с сервера, если URL-адрес хранится в виде строки?

Ответы [ 7 ]

533 голосов
/ 30 августа 2011

Если вы хотите получить содержимое веб-страницы в переменную, просто read ответ urllib.request.urlopen:

import urllib.request
...
url = 'http://example.com/'
response = urllib.request.urlopen(url)
data = response.read()      # a `bytes` object
text = data.decode('utf-8') # a `str`; this step can't be used if data is binary

Самый простой способ загрузить и сохранить файл - использовать функцию urllib.request.urlretrieve:

import urllib.request
...
# Download the file from `url` and save it locally under `file_name`:
urllib.request.urlretrieve(url, file_name)
import urllib.request
...
# Download the file from `url`, save it in a temporary directory and get the
# path to it (e.g. '/tmp/tmpb48zma.txt') in the `file_name` variable:
file_name, headers = urllib.request.urlretrieve(url)

Но имейте в виду, чтоurlretrieve считается устаревшим и может устареть (хотя и не знаю, почему).

Таким образом, самый правильный способ сделать это - использовать *Функция 1027 *urllib.request.urlopen возвращает файлоподобный объект, представляющий HTTP-ответ, и копирует его в реальный файл, используя shutil.copyfileobj.

import urllib.request
import shutil
...
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    shutil.copyfileobj(response, out_file)

Если это кажется слишком сложным, вы можете пойти проще и сохранить всю загрузку в объекте bytes, а затем записать его в файл.Но это хорошо работает только для небольших файлов.

import urllib.request
...
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    data = response.read() # a `bytes` object
    out_file.write(data)

Можно извлекать .gz (и, возможно, другие форматы) сжатые данные на лету, но такая операция, вероятно, требует HTTP-серверадля поддержки произвольного доступа к файлу.

import urllib.request
import gzip
...
# Read the first 64 bytes of the file inside the .gz archive located at `url`
url = 'http://example.com/something.gz'
with urllib.request.urlopen(url) as response:
    with gzip.GzipFile(fileobj=response) as uncompressed:
        file_header = uncompressed.read(64) # a `bytes` object
        # Or do anything shown above using `uncompressed` instead of `response`.
110 голосов
/ 23 января 2016

Я использую пакет requests всякий раз, когда я хочу что-то, связанное с HTTP-запросами, потому что его API очень легко начать с:

сначала, установите requests

$ pip install requests

тогда код:

from requests import get  # to make GET request


def download(url, file_name):
    # open in binary mode
    with open(file_name, "wb") as file:
        # get request
        response = get(url)
        # write to file
        file.write(response.content)
13 голосов
/ 18 января 2016

Надеюсь, я правильно понял вопрос: как загрузить файл с сервера, когда URL-адрес хранится в виде строки?

Я загружаю файлы и сохраняю их локально, используя следующий код:

import requests

url = 'https://www.python.org/static/img/python-logo.png'
fileName = 'D:\Python\dwnldPythonLogo.png'
req = requests.get(url)
file = open(fileName, 'wb')
for chunk in req.iter_content(100000):
    file.write(chunk)
file.close()
7 голосов
/ 17 июля 2018

Здесь мы можем использовать устаревший интерфейс urllib в Python3:

Следующие функции и классы перенесены из urllib модуля Python 2 (в отличие от urllib2). Они могут устареть в какой-то момент в будущем.

Пример (2 строки кода) :

import urllib.request

url = 'https://www.python.org/static/img/python-logo.png'
urllib.request.urlretrieve(url, "logo.png")
4 голосов
/ 13 января 2018

Вы можете использовать wget , который является популярным инструментом для загрузки оболочки.https://pypi.python.org/pypi/wget Это будет самый простой метод, так как ему не нужно открывать файл назначения.Вот пример.

import wget
url = 'https://i1.wp.com/python3.codes/wp-content/uploads/2015/06/Python3-powered.png?fit=650%2C350'  
wget.download(url, '/Users/scott/Downloads/cat4.jpg') 
0 голосов
/ 23 апреля 2019

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


from requests import get

# case when the response is byte array
url = 'some_image_url'

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


# case when the response is text
# Here unlikely if the reponse content is of type **iso-8859-1** we will have to override the response encoding
url = 'some_page_url'

response = get(url)
# override encoding by real educated guess as provided by chardet
r.encoding = r.apparent_encoding

with open('output', 'w', encoding='utf-8') as file:
    file.write(response.content)

0 голосов
/ 17 марта 2017
from urllib import request

def get(url):
    with request.urlopen(url) as r:
        return r.read()


def download(url, file=None):
    if not file:
        file = url.split('/')[-1]
    with open(file, 'wb') as f:
        f.write(get(url))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...