yulinfeng000/blive

有时运行一会就会报错

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了

报错截图
image
跟之前的错误 一样,我之前以为好了,今天下雨,可能网络会差一点,但是看直播还是很流畅的 ,系统开了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行 , 猜测,还是需要一个全局处理异常

image

这个属于new feature了,全局异常处理这个我考虑一下怎么加进去,你如果有最佳实践也欢迎提pr

#3 (comment)

再问一下是监听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包