吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1334|回复: 29
上一主题 下一主题
收起左侧

[Windows] B站所有评论&动态一键删除2.0

[复制链接]
跳转到指定楼层
楼主
闪电、犯贱 发表于 2026-1-5 15:21 回帖奖励
本帖最后由 闪电、犯贱 于 2026-1-5 22:05 编辑

因为这个程序较为简单,个人也比较懒,所以程序分开写的,比较粗糙,主要提供大致思路,勿喷,功能测试可用
以下是更新的删除动态操作方法
类似于获取评论并保存json,通过https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset=&host_mid=B站uid 会获取到你动态的全部信息,同样右键另存为json格式
打开软件用同样的方法,在编写过程中,dyn_type=1为转发他人动态,dyn_type=8 为自己视频动态,其余请自行观察,在本程序中,只删除转发他人动态功能
软件成品:
通过网盘分享的文件:delshare.exe(删除b站转发动态功能)
链接: https://pan.baidu.com/s/1h-1ToFqRP1CeP0K8VwoWuA?pwd=9euv 提取码: 9euv

源码放在原程序源码下方
  

最近aicu进行了风控,所以站内有一个B站评论一键清除软件暂时无法使用 ,所以偷巧利用类似的逻辑写了一个python软件
AICU官方网站:https://www.aicu.cc/ (如果出现删除成功但是AICU还是可以查询到是正常的,因为AICU的数据库并不是实时的,点击评论链接没有跳转到详细评论链接就是删除成功了
一、在浏览器通过https://api.aicu.cc/api/v3/search/getreply?uid=(输入自己的B站ID)&pn=1&ps=500&mode=0
获取到数据,右键另存为Json,这里每次只可以获取500条
二、通过B站获取cookie,登录网页版B站中F12 随便找一个网络活动点进去找到cookie复制即可

运行程序输入即可
注意:数据运行依赖AICU的数据进行,AICU数据更新存在延迟,有可能删了AICU还有,有可能新发的评论AICU没有识别到
这只是一个思路,关于删除弹幕等,具体操作一致,可以自行更改api进行操作
软件成品链接:
通过网盘分享的文件:delreply.exe(删除B站所有评论功能)
链接: https://pan.baidu.com/s/19zNfEL1liYVIz6QPOJrtHw?pwd=w8wp 提取码: w8wp


[Python] 纯文本查看 复制代码
import json
import requests
import re
from http.cookies import SimpleCookie

# -------------------------- 配置区 --------------------------
# JSON文件路径(将通过input获取)
JSON_FILE_PATH = ""
# B站删除评论API地址
DEL_REPLY_URL = "https://api.bilibili.com/x/v2/reply/del"
# B站Cookie字符串(将通过input获取)
COOKIE_STR = ""
# 请求超时时间(秒)
TIMEOUT = 10
# 请求间隔(秒,避免高频请求被风控)
REQUEST_INTERVAL = 1
# -------------------------------------------------------------

def parse_cookie(cookie_str: str) -> dict:
    """解析Cookie字符串为字典格式"""
    cookie = SimpleCookie()
    cookie.load(cookie_str)
    parsed_cookies = {}
    for key, morsel in cookie.items():
        parsed_cookies[key] = morsel.value
    return parsed_cookies

def load_reply_data(file_path: str) -> list:
    """加载JSON文件,提取所有评论的oid、rpid、type"""
    try:
        with open(file_path, "r", encoding="utf-8") as f:
            data = json.load(f)
        
        # 校验JSON结构
        if not data.get("code") == 0 or not data.get("data") or not data["data"].get("replies"):
            raise ValueError("JSON文件结构异常,未找到有效评论数据")
        
        # 提取核心字段
        reply_list = []
        for reply in data["data"]["replies"]:
            oid = reply.get("dyn", {}).get("oid")
            rpid = reply.get("rpid")
            type_id = reply.get("dyn", {}).get("type", 1)  # 默认type=1
            
            if not oid or not rpid:
                print(f"⚠️  跳过无效评论:缺少oid/rpid {reply}")
                continue
            
            reply_list.append({
                "oid": oid,
                "rpid": rpid,
                "type": type_id
            })
        
        print(f"✅ 成功加载 {len(reply_list)} 条评论数据")
        return reply_list
    
    except FileNotFoundError:
        print(f"❌ 未找到文件:{file_path}")
        return []
    except json.JSONDecodeError:
        print(f"❌ JSON文件解析失败,请检查文件格式")
        return []
    except Exception as e:
        print(f"❌ 加载评论数据失败:{str(e)}")
        return []

def delete_single_reply(session: requests.Session, oid: str, rpid: str, type_id: int, csrf: str) -> dict:
    """发送单条评论删除请求"""
    data = {
        "oid": oid,
        "type": type_id,
        "rpid": rpid,
        "csrf": csrf
    }
    
    headers = {
        "Origin": "https://www.bilibili.com",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
        "Content-Type": "application/x-www-form-urlencoded",
        "Referer": f"https://www.bilibili.com/video/BVxxxxxx/"  # 可替换为实际视频链接
    }
    
    try:
        response = session.post(
            url=DEL_REPLY_URL,
            headers=headers,
            data=data,
            timeout=TIMEOUT,
            allow_redirects=False
        )
        result = {
            "success": response.status_code == 200,
            "status_code": response.status_code,
            "response": response.json() if response.status_code == 200 else response.text,
            "oid": oid,
            "rpid": rpid
        }
        return result
    
    except requests.exceptions.Timeout:
        return {"success": False, "error": "请求超时", "oid": oid, "rpid": rpid}
    except requests.exceptions.ConnectionError:
        return {"success": False, "error": "连接错误", "oid": oid, "rpid": rpid}
    except Exception as e:
        return {"success": False, "error": str(e), "oid": oid, "rpid": rpid}

def batch_delete_replies():
    """批量删除评论主函数"""
    # 1. 解析Cookie并获取csrf
    parsed_cookies = parse_cookie(COOKIE_STR)
    csrf_token = parsed_cookies.get("bili_jct")
    if not csrf_token:
        print("❌ 未从Cookie中提取到bili_jct,请检查Cookie有效性")
        return
    
    # 2. 加载评论数据
    reply_list = load_reply_data(JSON_FILE_PATH)
    if not reply_list:
        return
    
    # 3. 创建会话(复用Cookie)
    session = requests.Session()
    session.cookies.update(parsed_cookies)
    
    # 4. 批量发送删除请求
    success_count = 0
    fail_count = 0
    fail_details = []
    
    print("\n🚀 开始批量删除评论...")
    for idx, reply in enumerate(reply_list, 1):
        print(f"\n[{idx}/{len(reply_list)}] 处理评论 rpid={reply['rpid']} oid={reply['oid']}")
        
        # 发送删除请求
        result = delete_single_reply(
            session=session,
            oid=reply["oid"],
            rpid=reply["rpid"],
            type_id=reply["type"],
            csrf=csrf_token
        )
        
        # 结果统计
        if result["success"]:
            success_count += 1
            print(f"✅ 删除成功:{result['response']}")
        else:
            fail_count += 1
            fail_details.append(result)
            print(f"❌ 删除失败:{result.get('error') or result['response']}")
        
        # 添加请求间隔(避免风控)
        import time
        time.sleep(REQUEST_INTERVAL)
    
    # 5. 输出最终统计
    print("\n" + "="*50)
    print(f"📊 批量删除完成!")
    print(f"总处理数:{len(reply_list)}")
    print(f"成功数:{success_count}")
    print(f"失败数:{fail_count}")
    
    if fail_details:
        print(f"\n❌ 失败详情:")
        for fail in fail_details:
            print(f"  rpid={fail['rpid']} oid={fail['oid']} 原因:{fail.get('error') or fail['response']}")

if __name__ == "__main__":
    # 获取用户输入
    print("="*50)
    print("B站评论批量删除工具")
    print("="*50)
    
    json_file = input("\n请输入JSON文件路径(默认:reply.json):").strip() or "reply.json"
    cookie_str = input("\n请输入B站Cookie字符串(包含SESSDATA、bili_jct等字段):").strip()
    
    if not cookie_str:
        print("\n❌ Cookie不能为空!")
        print("📌 获取方式:浏览器打开B站→F12→网络→随便找一个请求→请求头→复制Cookie字段")
    else:
        # 赋值给全局变量
        JSON_FILE_PATH = json_file
        COOKIE_STR = cookie_str
        batch_delete_replies()


动态删除功能源码:
[Python] 纯文本查看 复制代码
import json
import requests
import time
from http.cookies import SimpleCookie
from typing import List, Dict, Any

# -------------------------- 复用原有Cookie核心逻辑(从删除评论代码中提取) --------------------------
def parse_cookie(cookie_str: str) -> dict:
    """解析Cookie字符串为字典格式(原删除评论代码直接复用)"""
    cookie = SimpleCookie()
    cookie.load(cookie_str)
    parsed_cookies = {}
    for key, morsel in cookie.items():
        parsed_cookies[key] = morsel.value
    return parsed_cookies

def get_user_valid_cookie() -> str:
    """获取并校验用户输入的B站Cookie(原删除评论代码的输入逻辑)"""
    print("\n📌 Cookie获取方式:浏览器打开B站→F12→网络→随便找一个请求→请求头→复制Cookie完整字段")
    cookie_str = input("请输入B站Cookie字符串(包含SESSDATA、bili_jct):").strip()
    
    # 第一步:校验Cookie是否为空
    if not cookie_str:
        print("❌ 错误:Cookie字符串不能为空!")
        return ""
    
    # 第二步:解析Cookie并校验核心字段(bili_jct=csrf令牌,SESSDATA=登录状态)
    parsed_cookies = parse_cookie(cookie_str)
    missing_fields = []
    if not parsed_cookies.get("bili_jct"):
        missing_fields.append("bili_jct(CSRF令牌)")
    if not parsed_cookies.get("SESSDATA"):
        missing_fields.append("SESSDATA(登录状态)")
    
    if missing_fields:
        print(f"❌ 错误:Cookie缺少核心字段,无法完成登录验证:{', '.join(missing_fields)}")
        return ""
    
    print("✅ Cookie解析成功,包含有效登录字段和CSRF令牌")
    return cookie_str

# -------------------------- 原有动态删除核心逻辑(保留不变,仅适配Cookie) --------------------------
def extract_params_from_json(data: Any, results: List[Dict[str, Any]]) -> None:
    """
    递归遍历JSON数据,提取包含dyn_id_str、dyn_type、rid_str的params字段
    仅筛选出 dyn_type=1 的数据(符合批量删除要求)
    """
    # 如果是字典,遍历所有键值对
    if isinstance(data, dict):
        # 检查当前字典是否包含目标params结构
        if "params" in data:
            params = data["params"]
            # 严格校验:包含三个必填字段 + dyn_type=1
            if (isinstance(params, dict) and 
                all(key in params for key in ["dyn_id_str", "dyn_type", "rid_str"]) and
                params["dyn_type"] == 1):  # 仅保留需要删除的dyn_type=1类型
                results.append({
                    "dyn_id_str": params["dyn_id_str"],
                    "dyn_type": params["dyn_type"],
                    "rid_str": params["rid_str"]
                })
        
        # 递归遍历字典的每个值,支持任意层级JSON结构
        for value in data.values():
            extract_params_from_json(value, results)
    
    # 如果是列表,遍历每个元素继续递归
    elif isinstance(data, list):
        for item in data:
            extract_params_from_json(item, results)

def load_target_params(json_file_path: str) -> List[Dict[str, Any]]:
    """
    读取JSON文件,加载并筛选出符合条件的删除参数(dyn_type=1)
    """
    extracted_params = []
    
    try:
        # 读取并解析JSON文件
        with open(json_file_path, 'r', encoding='utf-8') as f:
            json_data = json.load(f)
        
        # 递归提取符合条件的params
        extract_params_from_json(json_data, extracted_params)
        print(f"✅ 成功从JSON文件提取到 {len(extracted_params)} 条待删除动态数据(dyn_type=1)")
        return extracted_params
    
    except FileNotFoundError:
        print(f"❌ 错误:文件 {json_file_path} 未找到,请检查路径是否正确")
        return []
    except json.JSONDecodeError:
        print(f"❌ 错误:文件 {json_file_path} 不是有效的JSON格式,请检查文件内容")
        return []
    except Exception as e:
        print(f"❌ 未知错误:{str(e)}")
        return []

def batch_delete_bilibili_dynamics(
    target_params: List[Dict[str, Any]],
    cookie_str: str,
    platform: str = "web"
) -> None:
    """
    批量调用B站删除动态API,执行删除操作(整合Cookie会话,解决未登录问题)
    """
    if not target_params:
        print("🚫 无待删除的动态数据,无需执行删除操作")
        return
    
    # 1. 解析Cookie,提取CSRF令牌(bili_jct)
    parsed_cookies = parse_cookie(cookie_str)
    csrf_token = parsed_cookies.get("bili_jct")
    
    # 2. B站删除动态API地址
    delete_api_url = "https://api.bilibili.com/x/dynamic/feed/operate/remove"
    
    # 3. 请求头(模拟浏览器请求,提高成功率)
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
        "Referer": "https://t.bilibili.com/",
        "Content-Type": "application/json;charset=UTF-8"
    }
    
    # 4. 创建Requests会话,复用Cookie(保持登录状态,解决未登录问题)
    session = requests.Session()
    session.cookies.update(parsed_cookies)  # 注入Cookie,维持登录态
    session.headers.update(headers)  # 复用请求头
    
    # 5. 遍历所有待删除参数,逐个执行删除请求
    success_count = 0
    fail_count = 0
    fail_records = []
    
    for idx, params in enumerate(target_params, 1):
        try:
            # 构造URL参数(platform + csrf)
            url_params = {
                "platform": platform,
                "csrf": csrf_token
            }
            
            # 构造请求载荷(JSON格式,对应动态唯一参数)
            request_payload = {
                "dyn_id_str": params["dyn_id_str"],
                "dyn_type": params["dyn_type"],
                "rid_str": params["rid_str"]
            }
            
            # 发送POST请求(使用会话发送,携带登录Cookie)
            response = session.post(
                url=delete_api_url,
                params=url_params,
                json=request_payload,
                timeout=10
            )
            
            # 解析响应结果,判断是否删除成功
            response_json = response.json()
            if response_json.get("code") == 0:
                success_count += 1
                print(f"[{idx}/{len(target_params)}] 成功删除动态:dyn_id_str={params['dyn_id_str']}")
            else:
                fail_count += 1
                error_msg = response_json.get("message", "未知错误")
                fail_records.append((params["dyn_id_str"], error_msg))
                print(f"[{idx}/{len(target_params)}] 失败删除动态:dyn_id_str={params['dyn_id_str']},错误信息:{error_msg}")
        
        except requests.exceptions.Timeout:
            fail_count += 1
            fail_records.append((params["dyn_id_str"], "请求超时"))
            print(f"[{idx}/{len(target_params)}] 失败删除动态:dyn_id_str={params['dyn_id_str']},错误信息:请求超时")
        except requests.exceptions.ConnectionError:
            fail_count += 1
            fail_records.append((params["dyn_id_str"], "网络连接错误"))
            print(f"[{idx}/{len(target_params)}] 失败删除动态:dyn_id_str={params['dyn_id_str']},错误信息:网络连接错误")
        except Exception as e:
            fail_count += 1
            fail_records.append((params["dyn_id_str"], str(e)))
            print(f"[{idx}/{len(target_params)}] 失败删除动态:dyn_id_str={params['dyn_id_str']},错误信息:{str(e)}")
        
        # 增加请求间隔(避免高频调用触发B站风控,保护账号安全)
        time.sleep(1)
    
    # 输出批量删除总结
    print("\n" + "="*50)
    print(f"批量删除操作完成!总计:{len(target_params)} 条,成功:{success_count} 条,失败:{fail_count} 条")
    if fail_records:
        print("\n失败详情:")
        for dyn_id, msg in fail_records:
            print(f"  dyn_id_str={dyn_id}:{msg}")

# -------------------------- 主入口(整合所有流程) --------------------------
if __name__ == "__main__":
    print("="*50)
    print("B站动态批量删除工具(已整合登录Cookie验证)")
    print("="*50)
    
    # 步骤1:获取用户输入的JSON文件路径
    JSON_FILE_PATH = input("\n请输入JSON文件路径(默认:all.json):").strip() or "all.json"
    
    # 步骤2:获取并校验用户输入的Cookie(解决未登录问题)
    valid_cookie = get_user_valid_cookie()
    if not valid_cookie:
        print("🚫 缺少有效Cookie,程序终止运行")
        exit(1)
    
    # 步骤3:加载待删除的动态参数(仅dyn_type=1)
    to_delete_params = load_target_params(JSON_FILE_PATH)
    
    # 步骤4:执行批量删除操作(携带有效Cookie,维持登录态)
    batch_delete_bilibili_dynamics(to_delete_params, valid_cookie)

json.png (47.79 KB, 下载次数: 1)

json.png

cookie.png (161.36 KB, 下载次数: 0)

cookie.png

运行.png (47.02 KB, 下载次数: 0)

运行.png

结束.png (54.82 KB, 下载次数: 0)

结束.png

屏幕截图 2026-01-05 215906.png (53.74 KB, 下载次数: 0)

更新删除动态功能

更新删除动态功能

免费评分

参与人数 6吾爱币 +6 热心值 +5 收起 理由
qsj521521 + 1 + 1 谢谢@Thanks!
Generic5909 + 1 + 1 谢谢@Thanks!
dogox + 1 + 1 我很赞同!
yamisxu + 1 + 1 热心回复!
Kanata7 + 1 + 1 谢谢@Thanks!
tcxd1993 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

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

推荐
 楼主| 闪电、犯贱 发表于 2026-1-5 19:58 |楼主
夹竹桃 发表于 2026-1-5 19:36
好用,另外提示一下,虽然每次是500条,但是可以通过调“pn”的参数,类似于页码,达到把所有评论都删掉的 ...

是的,可以通过调页码刷新。我这里说的是可能可能最近新发的评论,数据库还没有收录到,所以无法获取删除。在某一个时间之前的数据都可以获取到,调整页码就可以
推荐
夹竹桃 发表于 2026-1-5 19:36
好用,另外提示一下,虽然每次是500条,但是可以通过调“pn”的参数,类似于页码,达到把所有评论都删掉的效果,不用等数据库更新
沙发
360204878 发表于 2026-1-5 15:37
3#
Marken888 发表于 2026-1-5 15:40
学习一下思路
4#
fengqingzhi11 发表于 2026-1-5 15:59
这个厉害了,以后留着有用
5#
Raohz520 发表于 2026-1-5 16:06
有没有删除所有转发内容的
6#
fengtian99 发表于 2026-1-5 16:06
我B站的评论屈指可数,删除手动也够了,给需要的人吧
7#
小鸟会飞 发表于 2026-1-5 16:15
有没有测试过的 可行还是不行  先感谢一下
8#
Hmily 发表于 2026-1-5 16:22
@闪电、犯贱 这个板块需要编译成成品提供一下。
9#
halou 发表于 2026-1-5 16:28
第一次听说还有这样的网站,竟然还查的出来
10#
Kanata7 发表于 2026-1-5 16:29
还有这样的api可以查询,先存一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-1-7 15:13

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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