Как загрузить изображение с помощью запросов



Я пытаюсь загрузить и сохранить изображение из интернета с помощью python's requests модуль.



вот (рабочий) код, который я использовал:



img = urllib2.urlopen(settings.STATICMAP_URL.format(**data))
with open(path, 'w') as f:
f.write(img.read())


вот новый (нерабочий) код, используя requests:



r = requests.get(settings.STATICMAP_URL.format(**data))
if r.status_code == 200:
img = r.raw.read()
with open(path, 'w') as f:
f.write(img)


можете ли вы помочь мне о том, что атрибут из ответа из requests?

465   11  

11 ответов:

вы можете использовать response.raw file object, или повторите ответ.

использовать response.raw файлоподобный объект по умолчанию не будет декодировать сжатые ответы (с помощью GZIP или deflate). Вы можете заставить его распаковать для вас в любом случае, установив до True (requests С False для управления самим декодированием). Затем вы можете использовать shutil.copyfileobj() чтобы Python передавал данные в файл объект:

import requests
import shutil

r = requests.get(settings.STATICMAP_URL.format(**data), stream=True)
if r.status_code == 200:
    with open(path, 'wb') as f:
        r.raw.decode_content = True
        shutil.copyfileobj(r.raw, f)        

для итерации по ответу используйте цикл; итерация, подобная этой, гарантирует, что данные будут распакованы на этом этапе:

r = requests.get(settings.STATICMAP_URL.format(**data), stream=True)
if r.status_code == 200:
    with open(path, 'wb') as f:
        for chunk in r:
            f.write(chunk)

это будет читать данные в 128 байт куски; если вы чувствуете, что другой размер куска работает лучше, используйте Response.iter_content() метод с пользовательским размером куска:

r = requests.get(settings.STATICMAP_URL.format(**data), stream=True)
if r.status_code == 200:
    with open(path, 'wb') as f:
        for chunk in r.iter_content(1024):
            f.write(chunk)

обратите внимание, что вам нужно открыть файл назначения в двоичном режиме, чтобы убедиться, что python не пытается перевести новые строки для вас. Мы также установили stream=True, так что requests не загружает все изображение в память в первую очередь.

получите файл-как объект из запроса и скопировать его в файл. Это также позволит избежать чтения всего этого в память сразу.

import shutil

import requests

url = 'http://example.com/img.png'
response = requests.get(url, stream=True)
with open('img.png', 'wb') as out_file:
    shutil.copyfileobj(response.raw, out_file)
del response

Как насчет этого, быстрое решение.

import requests

url = "http://craphound.com/images/1006884_2adf8fc7.jpg"
response = requests.get(url)
if response.status_code == 200:
    with open("/Users/apple/Desktop/sample.jpg", 'wb') as f:
        f.write(response.content)

у меня такая же потребность в загрузке изображений с помощью запросов. Я сначала попробовал ответ Martijn Pieters, и он хорошо работает. Но когда я сделал профиль на этой простой функции, я обнаружил, что он использует так много вызовов функций по сравнению с urllib и urllib2.

Я тогда попробовал способ рекомендуется автор модуля запросов:

import requests
from PIL import Image
from StringIO import StringIO

r = requests.get('https://example.com/image.jpg')
i = Image.open(StringIO(r.content))

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

#!/usr/bin/python
import requests
from StringIO import StringIO
from PIL import Image
import profile

def testRequest():
    image_name = 'test1.jpg'
    url = 'http://example.com/image.jpg'

    r = requests.get(url, stream=True)
    with open(image_name, 'wb') as f:
        for chunk in r.iter_content():
            f.write(chunk)

def testRequest2():
    image_name = 'test2.jpg'
    url = 'http://example.com/image.jpg'

    r = requests.get(url)

    i = Image.open(StringIO(r.content))
    i.save(image_name)

if __name__ == '__main__':
    profile.run('testUrllib()')
    profile.run('testUrllib2()')
    profile.run('testRequest()')

результат для testRequest:

343080 function calls (343068 primitive calls) in 2.580 seconds

и результат для testRequest2:

3129 function calls (3105 primitive calls) in 0.024 seconds

это может быть проще, чем с помощью requests. Это единственный раз, когда я когда-либо предложу не использовать requests делать HTTP вещи.

два лайнера с помощью urllib:

>>> import urllib
>>> urllib.urlretrieve("http://www.example.com/songs/mp3.mp3", "mp3.mp3")

есть также хороший модуль Python с именем wget это довольно проста в использовании. Нашел здесь.

это демонстрирует простоту конструкции:

>>> import wget
>>> url = 'http://www.futurecrew.com/skaven/song_files/mp3/razorback.mp3'
>>> filename = wget.download(url)
100% [................................................] 3841532 / 3841532>
>> filename
'razorback.mp3'

наслаждайтесь.

Edit: вы также можете добавить out параметр to укажите путь.

>>> out_filepath = <output_filepath>    
>>> filename = wget.download(url, out=out_filepath)

следующий фрагмент кода загружает файл.

файл сохраняется с именем файла, как указано в указанном url.

import requests

url = "http://beispiel.dort/ichbineinbild.jpg"
filename = url.split("/")[-1]
r = requests.get(url, timeout=0.5)

if r.status_code == 200:
    with open(filename, 'wb') as f:
        f.write(r.content)

есть 2 основных способа:

  1. используя .content (самый простой / официальный) (см. ответ Жени Чжана):

    import io  # Note: io.BytesIO is StringIO.StringIO on Python2.
    import requests
    
    r = requests.get('http://lorempixel.com/400/200')
    r.raise_for_status()
    with io.BytesIO(r.content) as f:
        with Image.open(f) as img:
            img.show()
    
  2. используя .raw (см. Мартин Питерс-х):

    import requests
    
    r = requests.get('http://lorempixel.com/400/200', stream=True)
    r.raise_for_status()
    r.raw.decode_content = True  # Required to decompress gzip/deflate compressed responses.
    with PIL.Image.open(r.raw) as img:
        img.show()
    r.close()  # Safety when stream=True ensure the connection is released.
    

время оба не показывает заметной разницы.

вот более удобный ответ, который по-прежнему использует потоковое.

просто определите эти функции и вызовите getImage(). Он будет использовать то же имя файла, что и url-адрес и записывать в текущий каталог по умолчанию, но оба могут быть изменены.

import requests
from StringIO import StringIO
from PIL import Image

def createFilename(url, name, folder):
    dotSplit = url.split('.')
    if name == None:
        # use the same as the url
        slashSplit = dotSplit[-2].split('/')
        name = slashSplit[-1]
    ext = dotSplit[-1]
    file = '{}{}.{}'.format(folder, name, ext)
    return file

def getImage(url, name=None, folder='./'):
    file = createFilename(url, name, folder)
    with open(file, 'wb') as f:
        r = requests.get(url, stream=True)
        for block in r.iter_content(1024):
            if not block:
                break
            f.write(block)

def getImageFast(url, name=None, folder='./'):
    file = createFilename(url, name, folder)
    r = requests.get(url)
    i = Image.open(StringIO(r.content))
    i.save(file)

if __name__ == '__main__':
    # Uses Less Memory
    getImage('http://www.example.com/image.jpg')
    # Faster
    getImageFast('http://www.example.com/image.jpg')

The request кишки getImage() основаны на ответ здесь и внутренностях getImageFast() основаны на ответ выше.

Я собираюсь опубликовать ответ, поскольку у меня недостаточно репутации, чтобы сделать комментарий, но с wget, опубликованным Blairg23, вы также можете предоставить параметр out для пути.

 wget.download(url, out=path)

когда я пытаюсь запустить приведенный ниже код, изображение становится downaloded, но размер всегда ограничивается 34 КБ.

import requests
import shutil

r = requests.get(settings.STATICMAP_URL.format(**data), stream=True)
if r.status_code == 200:
with open(path, 'wb') as f:
    r.raw.decode_content = True
    shutil.copyfileobj(r.raw, f)  

и также, пожалуйста, дайте мне знать, что это настройки.STATICMAP_URL.формат (**данные), я использую свой usl вместо настроек.STATICMAP_URL.формат (**данные)

так же просто, как импортировать изображения и запросы

from PIL import Image
import requests

img = Image.open(requests.get(url, stream = True).raw)
img.save('img1.jpg')

Comments

    Ничего не найдено.