python - aiohttp.errors.ClientRequestError:无法写入请求正文
问题描述
我是 python 的初学者,但我正在尝试制作一个不和谐的机器人,当成员加入服务器时,它会发送欢迎消息。我想在聊天中发送用 PILLOW 修改的图像。我做到了:
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
如果有人知道我为什么会出现此错误...
解决方案
首先,在处理 asyncio 和协程时,您不应该使用 urllib 或 requests 来发出 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)
推荐阅读
- c# - 确定以管理员身份启动的进程是否已在 C# 中运行
- react-native - React Navigation onclick 到自定义组件
- regex - 使用 CryptoDeterministicConfig 和自定义信息类型对表格数据进行 Google Cloud DLP 标记化
- keras - 具有基数 10 Keras 填充序列的 int() 的无效文字
- mongodb - 如何按employeeId,itemId和tranDate分组显示一个项目行和tranDate?
- javascript - 如何使用 hapi js 在同一个请求处理函数中获取多个查询结果
- ios - 透明渐变在 UIView 类中不起作用
- python - 如何通过打包 python 脚本来解决此错误
- python - 无法导入“nlopt”python 的包
- excel - 文件位置不存在时的 VBA 语法