哔哩哔哩自动批量删除抽奖动态——使用篇

一、背景介绍

“梦想还是要有的,万一实现了呢”,秉承着这个信念,我关注了B站一位id名为“不是内定的”up主,他每天会转发一些抽奖动态,我直接参与他转发的动态即可。由于开奖时间各异,刚开始还能手动删除已开奖的动态,随着动态增加,后续已无心力一条一条再去删除抽奖动态,账号完全沦为抽奖号。为了删除已抽奖的动态,于是决定通过学习python,让python自动批量删除已过期的动态。
在这里插入图片描述

二、工具介绍

工欲善其事必先利其器,想使用python自动批量删除代码,肯定需要先安装python环境。下面是我使用的工具,由于环境和软件的安装配置不是本文重点,此处不过多赘述,网络上有很多教程,大家自己搜索:

三、代码文件

1、替换data.py里的参数配置文件

#data.py文件,将需变动的数据存放在此,便于替换
cookies = {
   #待补充,直接将通过脚本生成的cookies和此处做替换即可
}

headers = {
   #待补充,直接将通过脚本生成的headers和此处做替换即可
}

csrf =''#待补充,此处是字符串,比如csrf ='21de42957e8840dd09d8bdb2c08c3c2a'

host_mid = #待补充,此处是数值,比如:host_mid = 126369440

现在讲下如何替换上述文件里的参数

  1. 首先登录B站
  2. 点击自己的动态列表,从网页链接获取host_mid值

在这里插入图片描述

  1. 按F12健查看网页源代码,删除一条动态,不知道删除哪条可以现场创建一条后删除

在这里插入图片描述

  1. network模块找到找到删除数据链接的api接口,,可用ctrl+F快速查找“dynamic/feed/operate/remove”这段文本,右键复制运行脚本 Copy as cURL(bash)
    在这里插入图片描述

  2. 打开Convert curl commands to Python, JavaScript and more网站,将复制的脚本粘贴进去,选择python,复制生成的cookie,headers,csrf的值到data.py文件里
    在这里插入图片描述

2、运行代码removeDynamic,py

import datetime
import random
import time
import requests
from data import cookies,headers,csrf,host_mid

class Idstr():
    def __init__(self,id_str,orig_id_str):
        self.id_str = id_str
        self.orig_id_str = orig_id_str


def getid_strList():
    #获取首次动态列表
    response = requests.get(
        f'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset&host_mid={host_mid}&timezone_offset=-480&platform=web&features=itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote,decorationCard,forwardListHidden,ugcDelete,onlyfansQaCard&web_location=333.999&dm_img_list=[%7B%22x%22:1254,%22y%22:1465,%22z%22:0,%22timestamp%22:69,%22k%22:83,%22type%22:0%7D,%7B%22x%22:1192,%22y%22:-222,%22z%22:6,%22timestamp%22:328,%22k%22:123,%22type%22:0%7D]&dm_img_str=V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ&dm_cover_img_str=QU5HTEUgKEludGVsLCBJbnRlbChSKSBVSEQgR3JhcGhpY3MgKDB4MDAwMDhBNTYpIERpcmVjdDNEMTEgdnNfNV8wIHBzXzVfMCwgRDNEMTEpR29vZ2xlIEluYy4gKEludGVsKQ&dm_img_inter=%7B%22ds%22:[%7B%22t%22:0,%22c%22:%22%22,%22p%22:[57,19,19],%22s%22:[39,5076,5194]%7D],%22wh%22:[3660,5940,36],%22of%22:[54,108,54]%7D&x-bili-device-req-json=%7B%22platform%22:%22web%22,%22device%22:%22pc%22%7D&x-bili-web-req-json=%7B%22spm_id%22:%22333.999%22%7D&w_rid=8e093107e54b60fd35b846430c892e8e&wts=1726583398',
        cookies=cookies,
        headers=headers,
    ).json()
    data = response['data']
    id_strList = []  #保存动态列表参数值
    flag = True
    while flag:
        items = data['items']
        for item in items:
            if item.get('orig'):#因为抽奖动态都是转发的,我们原创的动态属于非转发,不会有orig数据,在此过滤掉,不做删除
                id_str = item['id_str']
                orig_id_str = item['orig']['id_str']
                new_idstr = Idstr(id_str,orig_id_str)#生成id_str对象
                id_strList.append(new_idstr)#将对象保存进列表
        offset = data['offset']#获取offset的值,以便获得后续的动态链接
        response = requests.get(
        f'https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset={offset}&host_mid={host_mid}&timezone_offset=-480&platform=web&features=itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote,decorationCard,forwardListHidden,ugcDelete,onlyfansQaCard&web_location=333.999&dm_img_list=[%7B%22x%22:1254,%22y%22:1465,%22z%22:0,%22timestamp%22:69,%22k%22:83,%22type%22:0%7D,%7B%22x%22:1192,%22y%22:-222,%22z%22:6,%22timestamp%22:328,%22k%22:123,%22type%22:0%7D]&dm_img_str=V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ&dm_cover_img_str=QU5HTEUgKEludGVsLCBJbnRlbChSKSBVSEQgR3JhcGhpY3MgKDB4MDAwMDhBNTYpIERpcmVjdDNEMTEgdnNfNV8wIHBzXzVfMCwgRDNEMTEpR29vZ2xlIEluYy4gKEludGVsKQ&dm_img_inter=%7B%22ds%22:[%7B%22t%22:0,%22c%22:%22%22,%22p%22:[57,19,19],%22s%22:[39,5076,5194]%7D],%22wh%22:[3660,5940,36],%22of%22:[54,108,54]%7D&x-bili-device-req-json=%7B%22platform%22:%22web%22,%22device%22:%22pc%22%7D&x-bili-web-req-json=%7B%22spm_id%22:%22333.999%22%7D&w_rid=8e093107e54b60fd35b846430c892e8e&wts=1726583398',
            cookies=cookies,
            headers=headers,
        ).json()
        data = response['data']
        if data['has_more']:#判断是否是最后一批动态数据,如果不是,循环继续,直到has_more为false
            continue
        else:
            flag = False #当循环为false时,说明是最后一批动态数据了,我们将本次获得的动态数据加入列表就能退出循环了
            items = data['items']
            for item in items:
                if item.get('orig'):
                    id_str = item['id_str']
                    orig_id_str = item['orig']['id_str']
                    new_idstr = Idstr(id_str, orig_id_str)
                    id_strList.append(new_idstr)
        sleep_time = random.randint(1, 4)#随机生成数字1,2,3,4
        time.sleep(sleep_time)#由于爬虫速度较快,短时间发送大量请求极易被服务器判定为恶意攻击,因此随机停顿1~4秒模拟是人工操作
    return id_strList

def isAlive(orig_id_str):
    params = {
        'business_id': orig_id_str,
        'business_type': '1',
        'csrf': csrf,
        'web_location': '333.1330',
    }

    res = requests.get(
        'https://api.vc.bilibili.com/lottery_svr/v1/lottery_svr/lottery_notice',
        params=params,
        cookies=cookies,
        headers=headers,
    ).json()
    sleep_time = random.randint(1, 4)#随机生成1-4秒延迟,避免过快访问接口而被封杀
    time.sleep(sleep_time)
    data = res['data']
    timestamp =data.get('lottery_time')
    if timestamp:
        lefttime = datetime.datetime.fromtimestamp(timestamp)#格式化时间戳
        now = datetime.datetime.now()#获取当前时间
        lefts = lefttime - now#时间戳是一段int值,其实我们也可以获取现在的时间戳,两个数值相减效率可能更快,但是我想看具体开奖时间,所以用了格式化方式
        return lefts > datetime.timedelta(0)#比较时间差是否大于0
    return True#非官方抽奖工具动态默认返回True,避免删除


def remove(id_str):
    sleep_time = random.randint(1, 4)#随机停滞1-4秒
    time.sleep(sleep_time)
    params = {
        'platform': 'web',
        'csrf': csrf,
    }

    json_data = {
        'dyn_id_str': id_str,
        'dyn_type': 1,
        'rid_str': id_str,
    }
    response = requests.post(
        'https://api.bilibili.com/x/dynamic/feed/operate/remove',
        params=params,
        cookies=cookies,
        headers=headers,
        json=json_data,
    )

def main():
    id_strList = getid_strList()
    id_len = len(id_strList)
    print('您转发的总动态数为:',id_len)
    id_len = id_len-1#让删除动态从末置位开始往前删除
    while id_len>=0:
        id_item = id_strList[id_len]
        if not isAlive(id_item.orig_id_str):
            print(id_item.orig_id_str,"抽奖动态已开奖","正在删除您的动态:",id_item.id_str)
            remove(id_item.id_str)
        id_len = id_len-1#不管动态是否需要删除,都更新id_len的值,因为我们是根据索引获取id_str的值,如果不递减,会陷入死循环
        print(id_len)


if __name__ == '__main__':
    main()

随着代码执行,从以前往近期逐条删除你参与的开奖了的官方抽奖动态,注意:本代码只删除官方抽奖的动态,你原创发布的或者是转发的非官方抽奖动态会得到保留,下面让我们看下执行效果。
在这里插入图片描述
成功从最开始的552条删除剩下73条,代码顺利完成任务,代码已上传到码云,有需要的朋友可以自取。如果感兴趣代码是如何实现的,可以看下面几篇文章,希望对你理解代码和后续更改内容有所帮助。

码云代码链接
哔哩哔哩自动批量删除抽奖动态——使用篇
哔哩哔哩自动批量删除抽奖动态解析篇(一)
哔哩哔哩自动批量删除抽奖动态解析篇(二)
哔哩哔哩自动批量删除抽奖动态解析篇(三)
哔哩哔哩自动批量删除抽奖动态解析篇(四)

你可以使用 Python 的 requests 库和 BeautifulSoup 库来实现这个爬虫。首先,你需要使用 requests 库向动态页面发送 GET 请求,获取动态页面的 HTML 代码。然后,你可以使用 BeautifulSoup 库解析 HTML 代码,找到抽奖相关的信息,比如抽奖的标题、抽奖的链接等等。最后,你可以使用 requests 库向抽奖链接发送 POST 请求,完成自动转发抽奖的操作。 具体的代码实现可以参考以下的示例: ```python import requests from bs4 import BeautifulSoup # 设置请求头,模拟浏览器访问 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} # 发送 GET 请求,获取动态页面的 HTML 代码 url = 'https://t.bilibili.com/' response = requests.get(url, headers=headers) html = response.text # 使用 BeautifulSoup 解析 HTML 代码,找到抽奖相关的信息 soup = BeautifulSoup(html, 'html.parser') lottery_title = soup.find('div', class_='card-title').text lottery_link = soup.find('a', class_='card-image')['href'] # 发送 POST 请求,完成自动转发抽奖的操作 data = { 'title': lottery_title, 'link': lottery_link, 'action': 'enter', 'csrf': 'xxxxxxxxxxxxxxxxxxxxx' # 这里需要填写你的 CSRF token } response = requests.post('https://t.bilibili.com/lottery/handler/Join', headers=headers, data=data) ``` 需要注意的是,这个示例中的 CSRF token 需要你自己从动态页面中获取。你可以使用浏览器的开发者工具,在 Network 标签页中找到抽奖链接对应的请求,然后在 Headers 标签页中找到 CSRF token。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值