Python aiohttp.errors.ClientRequestError:无法写入请求正文

Python aiohttp.errors.ClientRequestError:无法写入请求正文,python,bots,discord,Python,Bots,Discord,我是python的初学者,但我正在尝试创建一个discord bot,当成员加入服务器时,它会发送欢迎消息。我想在聊天时发送一张用枕头修改过的图片。我提出: if message.content == ".welcome": member = message.author url = member.avatar_url hdr = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit

我是python的初学者,但我正在尝试创建一个discord bot,当成员加入服务器时,它会发送欢迎消息。我想在聊天时发送一张用枕头修改过的图片。我提出:

if message.content == ".welcome":
        member = message.author
        url = member.avatar_url
        hdr = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
       'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
               'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
               'Accept-Encoding': 'none',
               'Accept-Language': 'en-US,en;q=0.8',
               'Connection': 'keep-alive'}

        req = urllib2.Request(url, headers=hdr)
        result = urllib2.urlopen(req)
        file = result.read()
        img = Image.open(io.BytesIO(file))

        name = str(member.display_name)
    #    await bot.send_message(testbot, member.avatar_url)
        await bot.send_file(testbot, img)
但我有一个错误:

Ignoring exception in on_message
Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/client_reqrep.py", line 407, in write_bytes
    result = stream.send(value)
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/helpers.py", line 191, in _gen_form_data
    yield from self._writer.serialize()
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/multipart.py", line 969, in serialize
    yield from part.serialize()
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/multipart.py", line 768, in serialize
    yield from self._maybe_encode_stream(self._serialize_obj())
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/multipart.py", line 781, in _serialize_obj
    return self._serialize_default(obj)
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/multipart.py", line 813, in _serialize_default
    raise TypeError('unknown body part type %r' % type(obj))
TypeError: unknown body part type <class 'PIL.WebPImagePlugin.WebPImageFile'>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.5/site-packages/discord/client.py", line 307, in _run_event
    yield from getattr(self, event)(*args, **kwargs)
  File "/home/pi/Desktop/bot.py", line 88, in on_message
    await bot.send_file(testbot, img)
  File "/home/pi/.local/lib/python3.5/site-packages/discord/client.py", line 1235, in send_file
    filename=filename, content=content, tts=tts)
  File "/home/pi/.local/lib/python3.5/site-packages/discord/http.py", line 137, in request
    r = yield from self.session.request(method, url, **kwargs)
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/client.py", line 555, in __iter__
    resp = yield from self._coro
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/client.py", line 202, in _request
    yield from resp.start(conn, read_until_eof)
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/client_reqrep.py", line 640, in start
    message = yield from httpstream.read()
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/streams.py", line 641, in read
    result = yield from super().read()
  File "/home/pi/.local/lib/python3.5/site-packages/aiohttp/streams.py", line 476, in read
    yield from self._waiter
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
aiohttp.errors.ClientRequestError: Can not write request body for https://discordapp.com/api/v6/channels/445990287152644096/messages
忽略on_消息中的异常
回溯(最近一次呼叫最后一次):
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/client_reqrep.py”,第407行,以写入字节表示
结果=stream.send(值)
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/helpers.py”,第191行,格式为数据
从self获得的收益。_writer.serialize()
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/multipart.py”,第969行,序列化
从part.serialize()获得的收益
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/multipart.py”,第768行,序列化
从self.产生。可能\u编码\u流(self.\u序列化\u obj())
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/multipart.py”,第781行,在
返回self.\u序列化\u默认值(obj)
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/multipart.py”,第813行,默认为序列化
raise TypeError('未知的车身部件类型%r'%type(obj))
TypeError:未知的身体部位类型
上述异常是以下异常的直接原因:
回溯(最近一次呼叫最后一次):
文件“/home/pi/.local/lib/python3.5/site packages/discord/client.py”,第307行,在运行事件中
getattr(自身,事件)的收益率(*args,**kwargs)
文件“/home/pi/Desktop/bot.py”,第88行,在on_消息中
等待bot.send_文件(testbot,img)
文件“/home/pi/.local/lib/python3.5/site packages/discord/client.py”,第1235行,在send_文件中
filename=filename,content=content,tts=tts)
文件“/home/pi/.local/lib/python3.5/site packages/discord/http.py”,请求中的第137行
r=self.session.request的收益(方法、url、**kwargs)
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/client.py”,第555行,在__
resp=自收益率。\u coro
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/client.py”,第202行,在请求中
从相应开始的产量(连接、读取到eof)
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/client_reqrep.py”,第640行,开始
message=来自httpstream.read()的产量
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/streams.py”,第641行,已读
结果=从super()获得的收益率。read()
文件“/home/pi/.local/lib/python3.5/site packages/aiohttp/streams.py”,第476行,已读
自食其果
文件“/usr/lib/python3.5/asyncio/futures.py”,第380行,在__
屈服自我——这告诉任务等待完成。
文件“/usr/lib/python3.5/asyncio/tasks.py”,第304行,在唤醒中
future.result()
文件“/usr/lib/python3.5/asyncio/futures.py”,第293行,在结果中
提出自己的意见
aiohttp.errors.ClientRequestError:无法写入的请求正文https://discordapp.com/api/v6/channels/445990287152644096/messages

如果有人知道我为什么会出现这个错误…

首先,在处理异步IO和协同路由时,您应该使用urllib或请求发出http请求,因为它们不是异步安全的(它们发出的请求是阻塞的)。在使用discord.py时,应该使用异步请求库(即aiohttp)发出请求

至于您的错误,
send_file
采用类似文件的对象,而不是PIL图像,因此您需要先将图像保存到文件或
BytesIO

from re import search
import aiohttp

@bot.event
async def on_message(m):
    member = m.author
    url = member.avatar_url
    file_name = search("/(\w+\.\w+)(?:\?.*?)?$", url)
    if file_name is None:
        file_name = "avatar.jpg"  # If there's a problem with my regex
    else:
        file_name = file_name.group(1)

    hdr = {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
        'Accept-Encoding': 'none',
        'Accept-Language': 'en-US,en;q=0.8',
        'Connection': 'keep-alive'}

    async with aiohttp.ClientSession() as client:
        async with client.get(url, headers=hdr) as req:
            bytes_image = await req.read()

    with io.BytesIO(bytes_image) as f:
        f.name = file_name
        img = Image.open(f)

    #######
    # do stuff with `img`
    #######

    with io.BytesIO() as f:
        f.name = file_name
        img.save(f)
        f.seek(0)
        await bot.send_file(m.channel, f)