如何使用请求下载图像
- 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(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
属性设置为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
不会先将整个图像下载到内存中。
解决方案 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:
主要有两种方式:
使用
.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()
使用
.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 | - | - | - |
wget | 不 | 不 | wget |
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.BytesIO
中PIL.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.Image
为numpy
数组
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 图片抓取和下载图像bs4
。urllib.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_url
到photo.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)
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)