如何使用aiohttp下载图片?

问题描述 投票:0回答:4

所以我有一个不和谐的机器人,我正在用它来学习Python。我有一个命令可以下载图像,编辑/合并它们,然后将编辑后的图像发送到聊天。我之前使用

requests
来执行此操作,但 Discord.py 的一位库开发人员告诉我,我应该使用
aiohttp
而不是
requests
。我找不到如何在
aiohttp
中下载图像,我尝试了很多东西,但都不起作用。

if message.content.startswith("!async"):
    import aiohttp
    import random
    import time
    import shutil
    start = time.time()
    notr = 0
    imagemake = Image.new("RGBA",(2048,2160))
    imgsave = "H:\Documents\PyCharmProjects\ChatBot\Images"
    imagesend = os.path.join(imgsave,"merged.png")
    imgmergedsend =os.path.join(imgsave,"merged2.png")
    with aiohttp.ClientSession() as session:
        async with session.get("http://schoolido.lu/api/cards/788/") as resp:
            data = await resp.json()
            cardsave = session.get(data["card_image"])
            with open((os.path.join(imgsave, "card.png")),"wb") as out_file:
                shutil.copyfileobj(cardsave, out_file)

这是我现在所拥有的,但仍然不起作用。

那么,有没有办法下载图片呢?

python aiohttp
4个回答
45
投票

写入文件时锁定循环。您需要使用 aiofiles。

import aiohttp        
import aiofiles

async with aiohttp.ClientSession() as session:
    url = "http://host/file.img"
    async with session.get(url) as resp:
        if resp.status == 200:
            f = await aiofiles.open('/some/file.img', mode='wb')
            await f.write(await resp.read())
            await f.close()

9
投票

所以我不久前就明白了:

if message.content.startswith("!async2"):
    import aiohttp
    with aiohttp.ClientSession() as session:
        async with session.get("http://schoolido.lu/api/cards/788/") as resp:
            data = await resp.json()
            card = data["card_image"]
            async with session.get(card) as resp2:
                test = await resp2.read()
                with open("cardtest2.png", "wb") as f:
                    f.write(test)

我收到的是回复,而不是图像回复


8
投票
pdf_url = 'https://example.com/file.pdf'
    
async with aiohttp.ClientSession() as session:
    async with session.get(pdf_url) as resp:
        if resp.status == 200:
            with open('file.pdf', 'wb') as fd:
                async for chunk in resp.content.iter_chunked(10):
                    fd.write(chunk)

虽然 read()、json() 和 text() 方法非常方便,但你应该 小心使用它们。所有这些方法都将整个响应加载到 内存。 例如,如果您想下载几千兆字节大小 文件时,这些方法将加载内存中的所有数据。相反,你可以 使用内容属性。它是一个实例 aiohttp.StreamReader 类。 gzip 和 deflate 传输编码 会自动为您解码:

https://docs.aiohttp.org/en/stable/client_quickstart.html#streaming-response-content


0
投票

向服务器打开一个 get 请求。如果它响应 HTTP 200,则打开写入流并在收到数据时流式传输数据。

import aiohttp        
import aiofiles

async with aiohttp.ClientSession() as session:
  async with session.get(download_url) as response:
    if response.status != 200:
      raise Exception('Got non-200 response!')

    async with aiofiles.open(filepath, 'wb') as file:
      async for data, _ in response.content.iter_chunks():
        await file.write(data)
© www.soinside.com 2019 - 2024. All rights reserved.