有时运行一会就会报错
Closed this issue · 18 comments
Task exception was never retrieved
future: <Task finished name='Task-1' coro=<BLiver.listen() done, defined at /opt/homebrew/lib/python3.9/site-packages/blive/framework.py:195> exception=TypeError("'NoneType' object is not subscriptable")>
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.9/site-packages/blive/framework.py", line 220, in listen
await asyncio.gather(tasks)
File "/opt/homebrew/lib/python3.9/site-packages/blive/framework.py", line 73, in process
return await asyncio.gather([f(ctx) for f in listeners])
File "/Users/huxinzhi/Developer/GitHub/blive/example/webhook.py", line 26, in listen_sc
username = msg.sender['name'] + '(' + str(msg.sender['id']) + ')'
File "/opt/homebrew/lib/python3.9/site-packages/blive/msg.py", line 182, in sender
medal_name=self.body["data"]["medal_info"]["medal_name"],
TypeError: 'NoneType' object is not subscriptable
有可能是b站改了消息结构,那么目前最快的临时解决办法就是不要套消息操作类,然后自己操作原始数据。我也会去查看消息结构尝试修复
目测sc的消息结构没大改动,你可以提供更多复现条件吗,源代码已经增加鲁棒性,尝试 pip install -U blive 升级包,升级后没问题的话我会在一周后关闭这个issue
谢谢,好的,我晚上再试一下。
原来的复现条件 : 在 crtl+c 终止后,马上开启大概率会遇到报这种错,第二次可以正常启动
想问一下,在app.on内部执行 request 会有问题吗
@app.on(Events.SUPER_CHAT_MESSAGE)
def listen_sc(ctx: BLiverCtx):
msg = SuperChatMsg(ctx.body)
…
requests.post(webhook_url, json=data)
app.run()
新版本应该没这样的问题了,异步方法内调用同步没啥大问题,建议传递requests超时时间参数防止阻塞太久。
还有问题吗
我发现,好像是网络断线的问题,今天网不好,一直遇到这个错误,能不能增加一个自动重连的功能
一直有的,能说一下什么错误导致程序down掉吗或者报错截图之类的,可能是有些网络超时异常没捕获到
我猜应该是你用的requests库抛出的网络中断错误导致程序挂掉,这种得你自己try catch了
报错截图
跟之前的错误 一样,我之前以为好了,今天下雨,可能网络会差一点,但是看直播还是很流畅的 ,系统开了clash 的 规则 代理
报错文字
Task exception was never retrieved
future: <Task finished name='Task-1' coro=<BLiver.listen() done, defined at /opt/homebrew/lib/python3.9/site-packages/blive/framework.py:195> exception=TypeError('can only concatenate str (not "NoneType") to str')>
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.9/site-packages/blive/framework.py", line 220, in listen
await asyncio.gather(*tasks)
File "/opt/homebrew/lib/python3.9/site-packages/blive/framework.py", line 73, in process
return await asyncio.gather(*[f(ctx) for f in listeners])
File "/Users/huxinzhi/Developer/GitHub/blive/example/webhook.py", line 38, in listen_sc
'description': price + '\t发送给: ' + anchor_uname + '\t发送时间: '+start_time,
TypeError: can only concatenate str (not "NoneType") to str
运行的代码,自己写了一个python3的文件,就把 SC 转发到discord 的频道里
from blive import BLiver, Events, BLiverCtx
from blive.msg import SuperChatMsg
import requests
import time
# 转发弹幕
app = BLiver(22637261) # 嘉然
webhook_url = 'xxxxxxxxx'
@app.on(Events.SUPER_CHAT_MESSAGE)
async def listen_sc(ctx: BLiverCtx):
msg = SuperChatMsg(ctx.body)
# description = (
# f"\n感谢 {msg.sender['name']}({msg.sender['medal']['medal_name']}:{msg.sender['medal']['medal_level']})的价值 {msg.price} 的sc\n\n\t{msg.content}\n"
# )
username = msg.sender['name'] + ' (uid: ' + str(msg.sender['id']) + ') 转发'
# 颜色 需要 16 进制转 10 进制 字符串
color = str(int(msg.color[1:], 16))
start_time = time.strftime(
'%Y-%m-%d %H:%M:%S', time.localtime(msg.start_time))
# 粉丝牌的主播名字
anchor_uname = msg.anchor_uname
price = '¥' + str(msg.price)
data = {
'username': username,
'avatar_url': msg.avatar_url,
'embeds': [{
'title': msg.content,
'description': price + '\t发送给: ' + anchor_uname + '\t发送时间: '+start_time,
'color': color
}]
}
print(start_time + '\t' + anchor_uname + '\t' +
username + ':' + price + '\t' + msg.content)
requests.post(webhook_url, json=data) # 转发利用 webhook 到discord
# 启动
app.run()
然后在 msg.py 文件增加了几个自己需要的数据段
@property # 头像
def avatar_url(self):
return dict_chain_get(self.body, "data.user_info.face")
@property
def anchor_uname(self):
return dict_chain_get(self.body, "data.medal_info.anchor_uname")
@property # 背景色
def color(self):
return dict_chain_get(self.body, "data.background_bottom_color")
我猜应该是你用的requests库抛出的网络中断错误导致程序挂掉,这种得你自己try catch了
hh,我去百度一下
msg.py 增加的字段你乐意的话可以提pr给我,NoneType那个错误只能说不要用+号拼接字符串,可以用 python的 f-string 这种写法。因为sc消息得到的你要拼接的某些值可能就是None。用+号拼接None就会抛出错误
再问一下是监听sc基本都能成功只是偶尔报错还是只要遇到sc就报错。如果是偶尔的话应该就是弹幕某个属性恰好为None,如果只要遇到sc就报错的话可能是属性没有获取对
新的错误测试,hh,运行时关掉代理,
future: <Task finished name='Task-1' coro=<BLiver.listen() done, defined at /opt/homebrew/lib/python3.9/site-packages/blive/framework.py:195>
exception=TypeError('catching classes that do not inherit from BaseException is not allowed')>
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.9/site-packages/urllib3/connectionpool.py", line 696, in urlopen
self._prepare_proxy(conn)
File "/opt/homebrew/lib/python3.9/site-packages/urllib3/connectionpool.py", line 964, in _prepare_proxy
conn.connect()
File "/opt/homebrew/lib/python3.9/site-packages/urllib3/connection.py", line 416, in connect
self.sock = ssl_wrap_socket(
File "/opt/homebrew/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 449, in ssl_wrap_socket
ssl_sock = _ssl_wrap_socket_impl(
File "/opt/homebrew/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 493, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
报错在 195行 , 猜测,还是需要一个全局处理异常
这个属于new feature了,全局异常处理这个我考虑一下怎么加进去,你如果有最佳实践也欢迎提pr
再问一下是监听sc基本都能成功只是偶尔报错还是只要遇到sc就报错。如果是偶尔的话应该就是弹幕某个属性恰好为None,如果只要遇到sc就报错的话可能是属性没有获取对
有可能,有些人就喜欢发空白SC
只运行了这一个监听模块, 监听sc基本都能成功只是偶尔报错,报错就停止运行了
那应该属性是拿对了,你可以避免使用+号拼接而改用 f-string 这样的写法,可以避免拼接None而抛出错误导致程序挂掉
问一下,怎样才能调用项目里的blive ,我用的是vs code,每次调用都是 pip3 里安装的blive,我想做一些修改,只能到 pip3 里面直接修改,不能用到git 的功能
from ..blive import BLiver, Events, BLiverCtx
from ..blive.msg import SuperChatMsg
报错,好像在直接运行的py文件是不能使用相对引用的
ImportError: attempted relative import with no known parent package
拷贝源代码的blive文件夹到项目里,卸载pip安装的blive包