吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1687|回复: 9
收起左侧

[Python 原创] B站新增关注查询脚本

  [复制链接]
jiugg 发表于 2024-4-24 21:44
本帖最后由 jiugg 于 2024-4-24 21:47 编辑

以前开发的脚本
可以生成趋势表
开源供大家参考
注意:频繁过快查询可能导致ip封禁
[Python] 纯文本查看 复制代码
import http.cookiejar
import math
import time
from tkinter import Button, Radiobutton, Entry, StringVar, Tk, IntVar, Checkbutton, messagebox
import matplotlib.pyplot as plt
import requests

session1 = requests.session()
session1.cookies = http.cookiejar.LWPCookieJar(filename = './config/bzcookie-lxswtt.txt')  # 需要加载有效的cookie信息文件,自行研究。
session1.cookies.load(ignore_discard = True)
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                  'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 '
                  'Edg/116.0.1938.69', 'Referer': "https://www.bilibili.com/"
}


def len_str(string):
    count = 0
    for ch in string:
        if ch >= '\u007f':
            count += 1
    return count


def get_follow_info(uid, page):  # 获取最新关注用户UID,uid为目标up主的uid,page为查询页码,最大20页,一页50个,因此最多可查最新关注的1000粉丝
    now_time = time.time()
    sub_dic = {}
    sub_list = []
    mid_list = []
    for i in range(1, page):
        url = f'https://api.bilibili.com/x/relation/followers?vmid={uid}&pn={i}'  # 拼接url,循环查询目标页数的所有粉丝信息
        resp2 = session1.get(url = url, headers = headers).json()
        if not len(resp2['data']['list']):
            print('粉丝数为0')
            return 0
        if resp2['code'] == 22118:
            print('由于该用户隐私设置,粉丝列表不可见')
            return 0
        sub_list += [li for li in resp2['data']['list']]  # 将粉丝信息添加到一个列表中
        time.sleep(0.1)
        print(f'{i}/{page - 1}')
        root.update()
    for lists in sub_list:  # 从粉丝信息列表提取出有用信息,生成uid列表和关键信息字典
        if (now_time - int(lists['mtime'])) > 24 * 3600 and c2.get():  # 实现查询最新24h的粉丝关注情况功能,想要修改时间可以修改数字大小
            break
        mid = lists['mid']
        mid_list.append(str(mid))
        sub_dic[f'{mid}'] = {
            'uname': lists['uname'], 'sub_time': time.strftime('%Y-%m-%d %X', time.localtime(lists['mtime'])), 'mtime': lists['mtime'], 'uid': mid,
            'vip': lists['vip']['vipType']
        }  # 保存关键信息,用户昵称,关注时间,uid,会员状态
    with open('mid.txt', 'w', encoding = 'utf-8') as f:  # 保存uid列表
        f.write(str(mid_list))
    get_follow_level(mid_list, sub_dic)  # 根据uid列表获取每个用户的等级
    sort(mid_list, sub_dic)  # 对数据进行统计
    # 绘制涨粉趋势图
    init = sub_dic[mid_list[-1]]['mtime']
    x_key = []
    y_value = []
    num = 1
    mid_list.reverse()
    for mid in mid_list:
        int1 = int(sub_dic[mid]['mtime']) - init
        x_key.append(int1 / 3600)
        y_value.append(num)
        num += 1
    x_key = [i - x_key[-1] for i in x_key]
    plt.plot(x_key, y_value)
    plt.show()


def get_follow_level(uid_all, all_dic):  # 实现获取用户等级功能
    vips = 0
    num = 0
    c = len(uid_all) // 50
    uid_lists = [uid_all[50 * i:50 * (i + 1)] for i in range(len(uid_all) // 50)]  # 将uid列表分割为50一组
    if len(uid_all) % 50 != 0:
        uid_lists.append(uid_all[50 * c:len(uid_all)])
    for uid in uid_lists:
        strs = ','.join(uid)  # 将50一组的uid列表用‘,’合并成一条字符串
        url = f'https://api.vc.bilibili.com/account/v1/user/cards?uids={strs}'  # 该api可以批量查询B站用户信息,最大50个,需要用','分割
        dic_temp = requests.get(url = url, headers = headers).json()
        for j in range(len(dic_temp['data'])):
            mid = dic_temp['data'][j]['mid']
            if dic_temp['data'][j]['name'] != '账号已注销':
                all_dic[f'{mid}']['level'] = dic_temp['data'][j]['level']  # 获取用户等级
        for k in range(len(dic_temp['data'])):  # 将用户信息打印到控制台中
            num += 1
            width = 36 - len_str(all_dic[uid_all[num - 1]]['uname'])
            if all_dic[uid_all[num - 1]]['uname'] != '账号已注销':
                print(
                    f"{num:<4}:{all_dic[uid_all[num - 1]]['uname']:^{width}}Lv:{all_dic[uid_all[num - 1]]['level']:<10}{all_dic[uid_all[num - 1]]['sub_time']:<20}  {all_dic[uid_all[num - 1]]['vip']}")
                if all_dic[uid_all[num - 1]]['vip']:
                    vips += 1
            else:
                print(f"\033[31m{num:<4}:{all_dic[uid_all[num - 1]]['uid']:^36}账号已注销!\033[0m")
            time.sleep(0.06)  # 设置延时,防止查询过快触发B站风控,尽量不要更改此参数
            root.update()
    with open('sub_dic.txt', 'w', encoding = 'utf-8') as f:  # 保存用户信息
        f.write(str(all_dic))
    print(f'有大会员记录的粉丝个数为:{vips}')  # 打印开过大会员的粉丝用户个数


def sort(uid_all, all_dic):  # 对用户信息进行统计
    sums = {6: 0, 5: 0, 4: 0, 3: 0, 2: 0, 1: 0, 0: 0}
    sum_per = {}
    new_sum = {}
    for uid in uid_all:
        if all_dic[f'{uid}']['uname'] != '账号已注销':
            key = all_dic[f'{uid}']['level']
            sums[key] = sums.get(key, 0) + 1
    for key in sums.keys():
        new_sum[f'Lv{key}'] = sums[key]
        sum_per[key] = round(sums[key] / len(uid_all), 4)
    new_sum['sum'] = len(uid_all)
    keys = list(new_sum.keys())
    print('\033[31m{:=^86}\033[0m'.format("等级统计"))
    print('{:^11}{:^11}{:^11}{:^11}{:^11}{:^11}{:^11}{:^11}'.format(keys[0], keys[1], keys[2], keys[3], keys[4], keys[5], keys[6], keys[7]))
    print('\033[33m{:^11}{:^11}{:^11}{:^11}{:^11}{:^11}{:^11}{:^11}\033[0m'.format(sums[6], sums[5], sums[4], sums[3], sums[2], sums[1], sums[0],
                                                                                   new_sum['sum']))
    print('\033[32m{:^11.2%}{:^11.2%}{:^11.2%}{:^11.2%}{:^11.2%}{:^11.2%}{:^11.2%}\033[0m'.format(sum_per[6], sum_per[5], sum_per[4], sum_per[3],
                                                                                                  sum_per[2], sum_per[1], sum_per[0]))


def start():  # 开始函数
    if v1.get():  # v1为查询粉丝数个数,最大值为1000,
        page = math.ceil(int(v1.get()) / 50) + 1  # 将粉丝个数转化成页数
        if page > 21:
            page = 21
    else:
        page = 21
        c2.set(1)  # 如果粉丝数输入框为空,则默认查询20页粉丝信息,同时自动勾选24h内的粉丝数
    if c1.get():  # c1为单选框变量值,如选择任意,则为0,即查询uid输入框的粉丝信息
        get_follow_info(c1.get(), page)  # 查询单选框目标的粉丝信息
    elif v2.get():
        get_follow_info(int(v2.get()), page)  # 如果UID输入框不为空,则查询输入框的UID目标的粉丝信息
    else:
        messagebox.showinfo(title = '提示', message = '请输入UID或勾选某个目标')
        return 0


if __name__ == '__main__':
    receiver = [{'name': '恬豆', 'uid': 1660392980}, {'name': '梨安', 'uid': 1900141897}, {'name': '又一', 'uid': 1217754423},
                {'name': '沐霂', 'uid': 1878154667}, {'name': '星瞳', 'uid': 401315430}, {'name': '露早', 'uid': 1669777785},
                {'name': '米诺', 'uid': 1778026586}, {'name': '柚恩', 'uid': 1795147802}, {'name': '莞儿', 'uid': 1875044092},
                {'name': '虞莫', 'uid': 1811071010}, {'name': '思诺', 'uid': 3537115310721781}, {'name': '心宜', 'uid': 3537115310721181},
                {'name': '嘉然', 'uid': 672328094}, {'name': 'asaki', 'uid': 194484313}, {'name': '任意', 'uid': 0}, ]  # 初始设置15个选项,可自行更改里面的数据,需注意UID对应关系
    root = Tk()
    root.geometry('360x140')
    root.title("新关注查询")
    c1, c2, v1, v2 = IntVar(), IntVar(), StringVar(), StringVar()
    Entry(root, textvariable = v1, width = 10).grid(row = 2, column = 4, rowspan = 1, columnspan = 1)  # 创建查询粉丝个数输入框,最大值1000
    Entry(root, textvariable = v2, width = 50).grid(row = 1, column = 1, rowspan = 1, columnspan = 5)  # 创建UID输入框
    for j in range(3):
        for i in range(5):
            rbtn = Radiobutton(root, text = receiver[j * 5 + i]['name'], value = receiver[j * 5 + i]['uid'], variable = c1)
            rbtn.grid(row = 3 + j, column = 1 + i, rowspan = 1, columnspan = 1, sticky = 'S')
    Button(root, height = 1, width = 30, text = '查询', command = start).grid(row = 2, column = 1, rowspan = 1, columnspan = 3)  # 按照目标列表创建单选框组件
    Checkbutton(root, text = "24h内", variable = c2, onvalue = 1, offvalue = 0).grid(row = 2, column = 5, sticky = "S")  # 创建查询24h新关注的复选框
    root.mainloop()

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| jiugg 发表于 2024-4-25 21:23
屏幕截图 2024-04-25 212142.png 屏幕截图 2024-04-25 212126.png wxl949389 发表于 2024-4-25 10:26可否附一张效果图

效果图:

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
wxl949389 + 1 + 1 谢谢@Thanks!

查看全部评分

adm471808 发表于 2024-4-24 23:45
fWiZsHh 发表于 2024-4-25 00:15
xixicoco 发表于 2024-4-25 00:33
脚本写的不错,膜拜
cokeseyo 发表于 2024-4-25 08:51
学习,膜拜大佬
wxl949389 发表于 2024-4-25 10:26
可否附一张效果图
xjls 发表于 2024-4-25 18:55
厉害,我都不懂这是啥
xuexiaogangi 发表于 2024-4-25 20:38
大神就是大神,我只能看看
eenny820 发表于 2024-4-27 13:01
嘶——,膜拜大佬
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 17:04

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表