我试图使用python的请求模块从网络下载并保存一张图像。

下面是我使用的(工作)代码:

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

下面是使用请求的新(无效)代码:

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)

你能帮我从请求中使用响应的什么属性吗?


当前回答

我的方法是使用回应。内容(blob)并以二进制模式保存到文件中

img_blob = requests.get(url, timeout=5).content
with open(destination + '/' + title, 'wb') as img_file:
     img_file.write(img_blob)

看看我的python项目,根据关键字从unsplash.com下载图像。

其他回答

我将发布一个答案,因为我没有足够的代表来发表评论,但使用Blairg23发布的wget,您还可以为路径提供一个out参数。

 wget.download(url, out=path)

我的方法是使用回应。内容(blob)并以二进制模式保存到文件中

img_blob = requests.get(url, timeout=5).content
with open(destination + '/' + title, 'wb') as img_file:
     img_file.write(img_blob)

看看我的python项目,根据关键字从unsplash.com下载图像。

这里有一个更友好的答案,仍然使用流媒体。

只需定义这些函数并调用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')

getImage()的请求内容基于这里的答案,getImageFast()的请求内容基于上面的答案。

你可以这样做:

import requests
import random

url = "https://images.pexels.com/photos/1308881/pexels-photo-1308881.jpeg? auto=compress&cs=tinysrgb&dpr=1&w=500"
name=random.randrange(1,1000)
filename=str(name)+".jpg"
response = requests.get(url)
if response.status_code.ok:
   with open(filename,'w') as f:
    f.write(response.content)

我同样需要使用请求下载图像。我首先尝试了Martijn Pieters的答案,效果很好。但是当我对这个简单的函数做了一个概要时,我发现与urllib和urllib2相比,它使用了太多的函数调用。

然后我尝试了请求模块作者推荐的方法:

import requests
from PIL import Image
# python2.x, use this instead  
# from StringIO import StringIO
# for python3.x,
from io 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