SocialSisterYi / bilibili-API-collect

哔哩哔哩-API收集整理【不断更新中....】
https://socialsisteryi.github.io/bilibili-API-collect/
Other
15.3k stars 1.73k forks source link

最近b站直播弹幕获取是否有点异常 #747

Open zhimingshenjun opened 1 year ago

zhimingshenjun commented 1 year ago

以前写的一直很稳的websocket抓包现在经常丢包 直播间刷了一堆了这边只能抓到几条信息

ProgramRipper commented 1 year ago

ws 连接时带上 User-Agent 头即可

whiteeat commented 1 year ago

亲测有效

nailvcoronation commented 1 year ago

ws 连接时带上 User-Agent 头即可

现在还好用吗...? 昨天开始加了UA也开始漏了,连了7000多个ws每秒只收得到十条弹幕。

而且只连一个或几个ws的时候还挺正常的,连多了就不行了。

whiteeat commented 1 year ago

ws 连接时带上 User-Agent 头即可

现在还好用吗...? 昨天开始加了UA也开始漏了,连了7000多个ws每秒只收得到十条弹幕。

前天我用还挺好,昨天没试

nailvcoronation commented 1 year ago

用python和go的两个弹幕库试了一下,连多了的时候都收不到弹幕。

Golang:

package main

import (
    "bytes"
    "encoding/json"
    "time"

    "github.com/Akegarasu/blivedm-go/client"
    "github.com/Akegarasu/blivedm-go/message"
    _ "github.com/Akegarasu/blivedm-go/utils"
    "github.com/go-resty/resty/v2"
    log "github.com/sirupsen/logrus"
)

type List = []interface{}
type Dict = map[string]interface{}

func main() {
    counterCh := make(chan int, 1000)
    startCh := make(chan int, 1000)
    go func() {
        count := 0
        runningClients := 0
        lastPollTime := time.Now()
        for {
            ticker := time.NewTicker(time.Second)
            select {
            case <-ticker.C:
                log.Infof("%v个弹幕客户端在过去%v秒内共获取了%v条弹幕", runningClients, time.Since(lastPollTime), count)
                lastPollTime = time.Now()
                count = 0
            case <-counterCh:
                count++
            case <-startCh:
                runningClients++
            }
        }
    }()
    httpClient := resty.New()
    httpClient.JSONUnmarshal = unmarshal
    var vups List
    httpClient.R().SetResult(&vups).Get("https://vup-json.xn--7dvy22i.com/vup-array.json")
    for idx, vup := range vups {
        if idx%(len(vups)/180) == 0 {
            time.Sleep(time.Second)
        }
        uid := vup.(Dict)["uid"].(json.Number).String()
        room := vup.(Dict)["room"].(json.Number).String()
        if room == "0" {
            continue
        }
        c := client.NewClient(room, uid)
        c.OnDanmaku(func(danmaku *message.Danmaku) {
            counterCh <- 1
        })
        go func() {
            err := c.Start()
            if err != nil {
                log.Warn(err)
            } else {
                startCh <- 1
            }
        }()
    }

    select {}
}

func unmarshal(data []byte, v interface{}) error {
    decoder := json.NewDecoder(bytes.NewReader(data))
    decoder.UseNumber()
    return decoder.Decode(&v)
}

Python:

import asyncio
from bilibili_api.live import LiveDanmaku
import requests

async def main():
    count = 0
    lock = asyncio.Lock()
    async def counter(msg):
        nonlocal count
        async with lock:
            count += 1
    resp = requests.get('https://vup-json.xn--7dvy22i.com/vup-array.json')
    resp = resp.json()
    for idx, r in enumerate(resp):
        if idx % (len(resp) // 180) == 0:
            await asyncio.sleep(1)
        if r["room"] == 0:
            continue
        room = LiveDanmaku(r["room"], max_retry = 10)
        room.add_event_listener('DANMU_MSG', counter)
        asyncio.create_task(room.connect())
    async def foo():
        nonlocal count
        while True:
            async with lock:
                print(count)
                count = 0
            await asyncio.sleep(1)
    await foo()

if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())

这两个库应该都是没有在连接ws的时候加UA的,但是我自己手写的加了UA情况也差不多。

cqrect commented 1 year ago

我用同一段代码尝试连接不同的直播间,发现部分直播间除了 STOP_LIVE_ROOM_LIST 拿不到其他东西。请教下是只是我的问题还是其他人也有这样的现象?