如何使用请求下载图像

2024-11-28 08:38:00
admin
原创
144
摘要:问题描述:我正在尝试使用 python 的模块从网络下载并保存图像requests。这是我使用的(工作)代码:img = urllib2.urlopen(settings.STATICMAP_URL.format(**data)) with open(path, 'w') as f: f.write(...

问题描述:

我正在尝试使用 python 的模块从网络下载并保存图像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


解决方案 1:

您可以使用response.raw文件对象,也可以迭代响应。

默认情况下,使用response.raw类似文件的对象不会解码压缩响应(使用 GZIP 或 deflate)。无论如何,您可以通过将decode_content属性设置为Truerequests将其设置为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不会先将整个图像下载到内存中。

解决方案 2:

从请求中获取类似文件的对象并将其复制到文件中。这也可以避免一次性将整个内容读入内存。

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

解决方案 3:

这样吧,一个快速的解决方案。

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)

解决方案 4:

我也需要使用请求下载图像。我首先尝试了 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

解决方案 5:

这可能比使用 更容易requests。这是我唯一一次建议不要使用requests来做 HTTP 操作。

双衬管使用urllib

>>> import urllib
>>> urllib.request.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'

享受。

编辑:您还可以添加out参数来指定路径。

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

解决方案 6:

以下代码片段下载文件。

文件将以其在指定 URL 中的文件名保存。

import requests

url = "http://example.com/image.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)

解决方案 7:

主要有两种方式:

  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()
  1. 使用.raw(参见Martijn Pieters 的回答):

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.

两者的时间安排没有明显差异。

解决方案 8:

就像导入图像和请求一样简单

from PIL import Image
import requests

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

解决方案 9:

总结

总结其他人的精彩答案。

方法需求requests需要 PIL需要 ...
requests.get->shutil是的-
requests.get->open(mode="wb")是的-
requests.get--> ByteIO-->Image.save是的是的-
urllib---
wgetwget
requests.get--> PIL.Image-->np.save是的是的numpy

使用shutil并输出解码后的原始内容requests.get

原始答案修改自https://stackoverflow.com/a/13137873/610569

import shutil
import requests

img_url = 'https://techcrunch.com/wp-content/uploads/2023/03/dpreview.jpg'

response = requests.get(img_url, stream=True)        
with open('dpreview.jpg', 'wb') as fout:
    response.raw.decode_content = True
    shutil.copyfileobj(response.raw, fout)             

将二进制文件直接写入文件 I/O

import requests

img_url = 'https://techcrunch.com/wp-content/uploads/2023/03/dpreview.jpg'

response = requests.get(img_url, stream=True) 

with open('dpreview.jpg', 'wb') as fout:
    for chunk in response:
        fout.write(chunk)

将内容流式传输到对象io.BytesIOPIL.Image并保存

from io import BytesIO

import requests
from PIL import Image

img_url = 'https://techcrunch.com/wp-content/uploads/2023/03/dpreview.jpg'

# Stream to BytesIO
response = requests.get(img_url, stream=True)
img = Image.open(BytesIO(response.content))
img.save('dpreview.jpg')


# Using raw content
response = requests.get(img_url, stream=True)
img = Image.open(response.raw)
img.save('dpreview.jpg')

使用urllib

原始答案来自https://stackoverflow.com/a/33866125/610569

import urllib

img_url = 'https://techcrunch.com/wp-content/uploads/2023/03/dpreview.jpg'

urllib.request.urlretrieve(img_url, "dpreview.jpg")

如果请求需要特定的用户代理,请从https://stackoverflow.com/a/69764951/610569

import urllib

opener=urllib.request.build_opener()
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582')]
urllib.request.install_opener(opener)

img_url = 'https://techcrunch.com/wp-content/uploads/2023/03/dpreview.jpg'

urllib.request.urlretrieve(img_url, "dpreview.jpg")

使用wget

import wget

img_url = 'https://techcrunch.com/wp-content/uploads/2023/03/dpreview.jpg'

wget.download(img_url, out='dpreview.jpg')

保存PIL.Imagenumpy数组

import requests
from PIL import Image

import numpy as np


img_url = 'https://techcrunch.com/wp-content/uploads/2023/03/dpreview.jpg'

response = requests.get(img_url, stream=True) 
img = Image.open(response.raw)

# Converts and save image into numpy array.
np.save('dpreview.npy', np.asarray(img))

# Loads a npy file to Image
img_arr = np.load('dpreview.npy')
img = Image.fromarray(img_arr.astype(np.uint8))

解决方案 10:

这就是我的做法

import requests
from PIL import Image
from io import BytesIO

url = 'your_url'
files = {'file': ("C:/Users/shadow/Downloads/black.jpeg", open('C:/Users/shadow/Downloads/black.jpeg', 'rb'),'image/jpg')}
response = requests.post(url, files=files)

img = Image.open(BytesIO(response.content))
img.show()

解决方案 11:

这是一个更加用户友好的答案,仍然使用流媒体。

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

request的胆量基于getImage()这里的答案,的胆量getImageFast()基于上面的答案。

解决方案 12:

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

 wget.download(url, out=path)

解决方案 13:

这是在谷歌上搜索如何使用请求下载二进制文件时出现的第一个响应。如果您需要使用请求下载任意文件,您可以使用:

import requests
url = 'https://s3.amazonaws.com/lab-data-collections/GoogleNews-vectors-negative300.bin.gz'
open('GoogleNews-vectors-negative300.bin.gz', 'wb').write(requests.get(url, allow_redirects=True).content)

解决方案 14:

我的方法是使用 response.content (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下载图像。

解决方案 15:

你可以做这样的事情:

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)

解决方案 16:

同意Blairg23的观点,使用urllib.request.urlretrieve是最简单的解决方案之一。

这里我想指出一点。有时它不会下载任何东西,因为请求是通过脚本(机器人)发送的,如果你想解析来自 Google 图片或其他搜索引擎的图片,你需要先传递user-agent请求headers,然后再下载图片,否则,请求将被阻止并抛出错误。

传递user-agent并下载图像:

opener=urllib.request.build_opener()
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582')]
urllib.request.install_opener(opener)

urllib.request.urlretrieve(URL, 'image_name.jpg')

在线 IDE 中的代码使用requests、、从 Google 图片抓取和下载图像bs4urllib.requests


或者,如果您的目标是从 Google、Bing、Yahoo!、DuckDuckGo(和其他搜索引擎)等搜索引擎抓取图像,那么您可以使用SerpApi。这是一个带有免费计划的付费 API。

最大的区别是,不需要弄清楚如何绕过搜索引擎的阻止或如何从 HTML 或 JavaScript 中提取某些部分,因为这些已经为最终用户完成了。

集成示例代码:

import os, urllib.request
from serpapi import GoogleSearch

params = {
  "api_key": os.getenv("API_KEY"),
  "engine": "google",
  "q": "pexels cat",
  "tbm": "isch"
}

search = GoogleSearch(params)
results = search.get_dict()

print(json.dumps(results['images_results'], indent=2, ensure_ascii=False))

# download images 
for index, image in enumerate(results['images_results']):

    # print(f'Downloading {index} image...')
    
    opener=urllib.request.build_opener()
    opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582')]
    urllib.request.install_opener(opener)

    # saves original res image to the SerpApi_Images folder and add index to the end of file name
    urllib.request.urlretrieve(image['original'], f'SerpApi_Images/original_size_img_{index}.jpg')

-----------
'''
]
  # other images
  {
    "position": 100, # 100 image
    "thumbnail": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQK62dIkDjNCvEgmGU6GGFZcpVWwX-p3FsYSg&usqp=CAU",
    "source": "homewardboundnj.org",
    "title": "pexels-helena-lopes-1931367 - Homeward Bound Pet Adoption Center",
    "link": "https://homewardboundnj.org/upcoming-event/black-cat-appreciation-day/pexels-helena-lopes-1931367/",
    "original": "https://homewardboundnj.org/wp-content/uploads/2020/07/pexels-helena-lopes-1931367.jpg",
    "is_product": false
  }
]
'''

免责声明,我在 SerpApi 工作。

解决方案 17:

要将图像从 下载image_urlphoto.jpg

import requests
from pathlib import Path

Path("photo.jpg").write_bytes(requests.get(image_url).content)

解决方案 18:

这是一个非常简单的代码

import requests

response = requests.get("https://i.imgur.com/ExdKOOz.png") ## Making a variable to get image.

file = open("sample_image.png", "wb") ## Creates the file for image
file.write(response.content) ## Saves file content
file.close()

解决方案 19:

下载图片

import requests
Picture_request = requests.get(url)
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1267  
  IPD(Integrated Product Development)即集成产品开发,是一套先进的、成熟的产品开发管理理念、模式和方法。随着市场竞争的日益激烈,企业对于提升产品开发效率、降低成本、提高产品质量的需求愈发迫切,IPD 项目管理咨询市场也迎来了广阔的发展空间。深入探讨 IPD 项目管理咨询的市场需求与发展,...
IPD集成产品开发流程   27  
  IPD(Integrated Product Development)产品开发流程是一套先进的、被广泛应用的产品开发管理体系,它涵盖了从产品概念产生到产品推向市场并持续优化的全过程。通过将市场、研发、生产、销售等多个环节紧密整合,IPD旨在提高产品开发的效率、质量,降低成本,增强企业的市场竞争力。深入了解IPD产品开发...
IPD流程中TR   31  
  IPD(Integrated Product Development)测试流程是确保产品质量、提升研发效率的关键环节。它贯穿于产品从概念到上市的整个生命周期,对企业的成功至关重要。深入理解IPD测试流程的核心要点,有助于企业优化研发过程,打造更具竞争力的产品。以下将详细阐述IPD测试流程的三大核心要点。测试策略规划测试...
华为IPD   26  
  华为作为全球知名的科技企业,其成功背后的管理体系备受关注。IPD(集成产品开发)流程作为华为核心的产品开发管理模式,在创新管理与技术突破方面发挥了至关重要的作用。深入剖析华为 IPD 流程中的创新管理与技术突破,对于众多企业探索自身发展路径具有重要的借鉴意义。IPD 流程概述IPD 流程是一种先进的产品开发管理理念和方...
TR评审   26  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用