B_zhan直播间弹幕抓取

16 篇文章 9 订阅
10 篇文章 0 订阅

前两天研究了一下B_zhan的直播间,其实B_zhan的用户体量很少。我最近几个月一直在搞B_zhan,几乎B_zhan能pa的都被我试过。其中还包括包括私信,大批量的私信。不过再三声明哈,我本人是为了学习,为了技术而去研究,并非用于商业用途。

这里我把B站直播间弹幕的代码发出来,就当作做个记录吧,万一以后用到就不用我重新去写了。

import pymysql
import requests,time

db = pymysql.connect("host", "root", "password", "table", charset='utf8mb4')

cur = db.cursor()

def work_1(room_id,f):
    url = "脱敏处理"+str(room_id)
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
        # 'Cookie': 'buvid3=DA5846C7-646E-0904-0458-012E677A9B3A55357infoc; innersign=1'
        # 'cookie': '_uuid=B6610A168-E31D-5FE2-F6AA-6CBF474BD8F548855infoc; buvid3=2E3F120D-4845-237F-10E5-E098A837497F62582infoc; b_nut=1652889062; buvid4=20BD8A06-CE2E-4E53-7154-8708F50D709962582-022051823-9aP+lNBWQG3ZSvnKpWr+YXGoWltZK/meRYpL5S9DSBIfa9D7j0ATkg%3D%3D; B_SESSDATA=987711b4%2C1660665085%2C8fe23%2A59; bili_b_jct=2986eebd355f09bf706a9d8d59004920; B_DedeUserID=12717125; B_DedeUserID__ckMd5=ac85c1bd5132323c; B_sid=8znagbm4; buvid_fp_plain=undefined; CURRENT_BLACKGAP=0; blackside_state=0; rpdid=|(kmJY~k)|lR0J\'uYlkmYJm~J; fingerprint=2a02d0bcfbad3f8893500097c177b3e6; buvid_fp=f4d3163daaf209e5621bbe64b1e7330e; SESSDATA=9b054a26%2C1668516676%2Cfa1f8%2A51; bili_jct=c3a19d545ba134d1205c520b9819c39b; DedeUserID=23854230; DedeUserID__ckMd5=45af4dc91dbbc312; sid=6he4s3h6; bp_video_offset_489388000=635614817268269000; i-wanna-go-back=-1; b_ut=5; innersign=1; CURRENT_FNVAL=4048; bp_video_offset_23854230=662173756825796600; b_timer=%7B%22ffp%22%3A%7B%22333.866.fp.risk_2E3F120D%22%3A%22180D7DD8CB1%22%2C%220.0.fp.risk_2E3F120D%22%3A%22180D82148E1%22%2C%22333.130.fp.risk_2E3F120D%22%3A%22180DC5DEA98%22%2C%22333.999.fp.risk_2E3F120D%22%3A%22180DD67FD7C%22%2C%22888.2421.fp.risk_2E3F120D%22%3A%22180D8383D38%22%2C%22777.5.0.0.fp.risk_2E3F120D%22%3A%22180D8383D89%22%2C%22333.788.fp.risk_2E3F120D%22%3A%22180E1E6BDB1%22%2C%22333.937.fp.risk_2E3F120D%22%3A%22180E2135465%22%2C%22333.858.fp.risk_2E3F120D%22%3A%22180DC610F9B%22%2C%22333.1007.fp.risk_2E3F120D%22%3A%22180DCEDD446%22%7D%7D; PVID=4; b_lsid=EF104B5F9_180E5612158',

    }
    Session = requests.session()
    while True:
        proxies = IP()
        try:
            resp = Session.get(url=url,headers=headers,proxies=proxies)
            content = resp.json()
        except:
            content["code"] == 0

        if content["code"] == 0:
            for i in content["data"]["room"]:
                text = i["text"]  #弹幕内容
                timeline = i["timeline"]    #弹幕发送时间
                nickname = i["nickname"]    # 弹幕发送者昵称
                user_id = i["uid"]          #弹幕发送者uid
                if len(i["medal"]) == 0:    # 弹幕发送者等级
                    medal = 0
                else:
                    medal = i["medal"][0]
                rnd = i["rnd"]
                # f.write(nickname+"\t"+str(medal)+"\t"+str(timeline)+"\t"+text+"\n")
                # print(nickname+"\t"+str(medal)+"\t"+str(timeline)+"\t"+text)
                sql = f'INSERT INTO B_danmu (room_id,user_id,`name`,timeline,text,medal) VALUES (' \
                    f' "{room_id}","{user_id}","{nickname}","{timeline}","{text}","{medal}" )'
                get_myql(sql, state="INSERT")
        time.sleep(5)

def get_myql(sql,state):
    if state == "select":
        cur.execute(sql)
        list = cur.fetchall()
        return list
    elif state == "INSERT":

        try:
            cur.execute(sql)
            db.commit()
            print(sql)
            print("插入成功!!!")
        except pymysql.err.IntegrityError:
            pass
            # print("重复")


def IP():
    # 代理服务器
    proxyHost = "************"
    proxyPort = "9020"
    # 代理隧道验证信息
    proxyUser = "********"
    proxyPass = "********"

    proxyMeta = "************************" % {
        "host": proxyHost,
        "port": proxyPort,
        "user": proxyUser,
        "pass": proxyPass,
    }

    proxies = {
        "http": proxyMeta,
        "https": proxyMeta,
    }
    return proxies

if __name__ == '__main__':
    t = str(int(time.time()))
    room_id = ""  #直播间的房间号
    with open('直播间弹幕',"a",encoding="utf-8") as f:
        work_1(room_id,f)

上面其实就用到了一个链接:

这里的URL转码了一下,base64了一下。

这是人家平台本身的接口,我们拿来借用学习。

起初我以为下图这里的是直播间ID

直到后面我怎么看接口怎么觉得接口没问题,那为啥拿下来的数据每次都一样,后面我就重新F12中找了找,找到了正确的ID,抓取下来的数据就正常了。

正确的ID是在下图这里。

另外,我把接口返回数据再说下,有个同学他不太懂,我等下写完要把文章分享过去让他看一下,尽量写的详细点,让他能看明白。

这里面我们主要是拿room中的数据,里面有我们想要的信息。

其实这里已经很简单了,text嘛,弹幕内容;nickname,昵称;还有timeline是用户发布时间;这里如果要看用户等级,在medal中的第一个元素中。 

为什么不用admin中的数据,感觉样式和room一模一样,但是多刷新两下你会发现admin中的数据像是类似于榜单这样的,所以造成刷新了两三次得到的数据一模一样。

另外额外说一个坑,就是B_zhan可能用户体量比较小,然后看直播的人也不多,发弹幕的少,刷新的时候,尤其是遇到观看人数少的那种,发现room中的数据一模一样,其实这不是接口原因,而是单纯的没人发弹幕。。。。。。。。所以我设置了5秒抓取一次,这个可以根据实际情况来定。既然发弹幕的人少,每次返回的数据中可能会有和上次重叠的,那怎么办?我是存在数据库中,以用户ID和时间两个字段为主键,因为它肯定不存在一个人同一时间发不了两个弹幕的情况,所以这样就完美的避开了这个坑。

OK,就这样吧,其实这个B_zhan项目还是很简单的,主要是给某位同学看下,要是我自己去写,我估计就直接贴个代码上去,其他的我就不管了。写完了,洗澡睡觉休息。

这段代码是一个简单的四则运算表达式的计算器,通过栈的数据结构来实现。以下是对代码的详细注解: ```c++ else if (zhan[i] == '+' || zhan[i] == '-' || zhan[i] == '*' || zhan[i] == '/' || zhan[i] == '%' || zhan[i] == '(' || zhan[i] == ')') { ``` 这是一个 if 语句,判断当前字符是否为加号、减号、乘号、除号、取模、左括号或右括号之一。 ```c++ if (zhan[i] == '(') { op_top++; op_stack[op_top] = '('; } ``` 如果当前字符为左括号,则将其加入操作符栈中。 ```c++ else if (zhan[i] == ')') { while (op_top >= 0 && op_stack[op_top] != '(') { char op = op_stack[op_top]; op_top--; double b = num_stack[num_top]; num_top--; double a = num_stack[num_top]; num_top--; double result = 0; if (op == '+') { result = a + b; } else if (op == '-') { result = a - b; } else if (op == '*') { result = a * b; } else if (op == '/') { result = a / b; } else if (op == '%') { result = (int)a % (int)b; } num_top++; num_stack[num_top] = result; } op_top--; } ``` 如果当前字符为右括号,则将操作符栈中的操作符和数字栈中的数字取出,进行计算并将结果压入数字栈中,直到遇到左括号。最后将左括号从操作符栈中弹出。 ```c++ else { while (op_top >= 0 && get_priority(op_stack[op_top]) >= get_priority(zhan[i])) { char op = op_stack[op_top]; op_top--; double b = num_stack[num_top]; num_top--; double a = num_stack[num_top]; num_top--; double result = 0; if (op == '+') { result = a + b; } else if (op == '-') { result = a - b; } else if (op == '*') { result = a * b; } else if (op == '/') { result = a / b; } else if (op == '%') { result = (int)a % (int)b; } num_top++; num_stack[num_top] = result; } op_top++; op_stack[op_top] = zhan[i]; } ``` 如果当前字符为加号、减号、乘号、除号或取模,则将操作符栈中优先级大于等于当前操作符的操作符取出,与数字栈中的数字进行计算,并将结果压入数字栈中。最后将当前操作符压入操作符栈中。 ```c++ int get_priority(char op) { if (op == '+' || op == '-') { return 1; } else if (op == '*' || op == '/' || op == '%') { return 2; } else { return 0; } } ``` 这是一个辅助函数,用于返回操作符的优先级。优先级为1的是加减号,优先级为2的是乘除号和取模号,其他操作符的优先级为0。 注:本段代码中,num_stack 是用于存储数字的栈,op_stack 是用于存储操作符的栈,num_top 和 op_top 分别是数字栈和操作符栈的栈顶指针。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值