bilibili-API-collect icon indicating copy to clipboard operation
bilibili-API-collect copied to clipboard

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

Open zhimingshenjun opened this issue 2 years ago • 6 comments

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

zhimingshenjun avatar Jul 18 '23 14:07 zhimingshenjun

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

ProgramRipper avatar Jul 19 '23 20:07 ProgramRipper

亲测有效

whiteeat avatar Jul 20 '23 10:07 whiteeat

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

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

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

nailvcoronation avatar Jul 28 '23 03:07 nailvcoronation

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

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

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

whiteeat avatar Jul 28 '23 03:07 whiteeat

用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情况也差不多。

nailvcoronation avatar Jul 28 '23 09:07 nailvcoronation

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

cqrect avatar Nov 15 '23 08:11 cqrect