尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从零搭建B站自动化任务机器人:robotbilibili架构设计与实践

从零搭建B站自动化任务机器人:robotbilibili架构设计与实践 之前一直想实现一个 B 站个人自动化任务机器人每天手动签到、领银瓜子、做互动任务实在太麻烦。网上资料零散大部分只讲单个接口怎么调没有完整工程思路。这次结合 robotbilibili 的常见实践整理一套从零搭建 B 站自动化机器人的完整方案包含项目结构、核心代码、任务调度、常见报错处理适合想要入门 Python 自动化项目的新手也适合想快速搭建个人机器人框架的开发者。1. robotbilibili 是什么从需求到实现1.1 为什么需要 B 站机器人B 站用户每天会有不少重复操作比如每日登录签到获取经验值和硬币奖励。观看视频、分享视频完成每日任务。领取银瓜子、硬币任务奖励。给自己的番剧、直播进行每日签到。定时清理私信、处理粉丝牌等操作。这些操作单个看都很简单但每天重复执行会消耗大量时间。robotbilibili 就是把这类操作脚本化、自动化通过模拟浏览器请求或调用 B 站公开接口代替人工完成重复任务。从技术角度看robotbilibili 本质上是一个基于 HTTP 请求的自动化任务框架它通常使用 Python 作为主要开发语言配合 requests、APScheduler、日志库等工具实现任务定义、定时触发、执行结果记录等完整流程。1.2 它能解决什么问题这类机器人项目主要解决三个层面的问题问题人工处理机器人处理时间成本每天手动打开 B 站完成任务定时任务自动执行稳定性容易遗忘、操作流程不一致固定流程、可重复执行可观测性无法记录操作历史每次执行都有日志记录1.3 需要明确的边界在开始之前必须强调一个前提B 站自动化机器人适用于学习、个人效率工具、合规自动化场景。使用机器人时不应当批量注册、批量养号。刷播放量、刷点赞、刷评论。绕过风控策略、验证码识别。用于任何违反 B 站社区规则和用户协议的行为。本文的核心目标是提供一个技术框架让读者理解 HTTP 自动化任务的设计方式。具体使用场景必须由你自己把控边界合法合规使用。建议在个人小号、测试环境或明确允许自动化的功能上进行验证。2. 环境准备与项目设计2.1 开发环境编写 robotbilibili 机器人不需要特别复杂的环境推荐以下配置操作系统Windows 10 / 11、macOS、Linux 均可 Python3.8 及以上版本 依赖管理pip 或 poetry 开发工具任意 Python IDE 或 VS Code主要依赖库pip install requests pip install APScheduler pip install python-dotenv pip install loguru库名用途requests发送 HTTP 请求调用 B 站接口APScheduler定时任务调度python-dotenv管理 Cookie 等敏感配置loguru日志输出和记录2.2 版本说明B 站接口随着时间推移会调整不同版本的接口字段名、请求方式可能发生变化。本文示例代码以通用思路为主实际使用时需要根据你抓取到的接口信息调整请求地址和参数。这里提供的代码框架更关注工程结构接口适配需要根据当前实际情况动态修正。2.3 项目结构设计在设计 robotbilibili 时建议从以下几个模块入手robotbilibili/ ├── main.py # 入口文件负责初始化调度器 ├── config.py # 配置读取 ├── requirement.txt # 依赖清单 ├── core/ │ ├── __init__.py │ ├── http_client.py # 请求封装统一处理 Cookie │ ├── scheduler.py # 定时任务模块 │ └── logger.py # 日志初始化 ├── tasks/ │ ├── __init__.py │ ├── base_task.py # 任务基类 │ ├── sign_task.py # 签到任务示例 │ └── video_task.py # 视频相关任务示例 ├── utils/ │ ├── __init__.py │ └── cookie_utils.py # Cookie 解析与处理 └── logs/ # 日志目录模块职责说明core 存放基础组件例如 HTTP 请求封装、日志初始化、调度器配置。tasks 存放具体的业务任务每个任务继承 BaseTask 基类实现统一执行接口。utils 存放通用工具函数。main.py 只负责组装模块不写具体业务逻辑。这样的好处是任务和请求层解耦新增一个任务只需要在 tasks 目录下新增一个文件不需要修改其他模块。3. 核心模块拆解3.1 Cookie 处理B 站接口的身份认证主要依赖请求头中的 Cookie。Cookie 通常包含SESSDATA、bili_jct、DedeUserID等关键字段。一般的流程是打开浏览器登录 B 站账号。通过浏览器的开发者工具F12找到任意的 api.bilibili.com 请求。复制请求头中的 Cookie 内容。将 Cookie 写入本地配置文件机器人请求时自动携带。使用python-dotenv管理 Cookie 更安全# config.py import os from dotenv import load_dotenv load_dotenv() class Config: COOKIE os.getenv(BILI_COOKIE, ) UA os.getenv(BILI_UA, Mozilla/5.0) RETRY_TIMES int(os.getenv(RETRY_TIMES, 3))在.env文件中存放BILI_COOKIE你的完整Cookie内容 BILI_UAMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36需要注意的是Cookie 属于敏感信息。如果项目需要上传到 Git 仓库一定要把.env文件加入到.gitignore中避免泄露账号凭证。3.2 HTTP 请求封装直接在每个任务中使用requests.get写请求会很混乱。建议统一封装一个 HttpRequest 类集中处理请求头拼接。Cookie 自动附加。超时控制。请求重试。返回数据的 JSON 解析。# core/http_client.py import time import requests from loguru import logger from config import Config class HttpClient: def __init__(self): self.session requests.Session() self.session.headers.update({ User-Agent: Config.UA, Referer: https://www.bilibili.com/, Origin: https://www.bilibili.com, Cookie: Config.COOKIE, }) def get(self, url, paramsNone, timeout10, retry_timesNone): return self._request(GET, url, paramsparams, timeouttimeout, retry_timesretry_times) def post(self, url, dataNone, timeout10, retry_timesNone): return self._request(POST, url, datadata, timeouttimeout, retry_timesretry_times) def _request(self, method, url, retry_timesNone, **kwargs): retry_times retry_times or Config.RETRY_TIMES for attempt in range(1, retry_times 1): try: response self.session.request(method, url, timeoutkwargs.get(timeout, 10), paramskwargs.get(params), datakwargs.get(data)) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: logger.warning(f请求失败: {url}第 {attempt} 次重试原因: {e}) if attempt retry_times: raise time.sleep(attempt * 2)封装后的效果请求失败自动重试。统一日志记录。双端方法调用简单任务模块只需要关注具体接口逻辑。3.3 任务基类设计为了让多个任务都可以被调度器统一管理定义任务基类# tasks/base_task.py from abc import ABC, abstractmethod from loguru import logger class BaseTask(ABC): name base_task abstractmethod def run(self): 执行任务的具体逻辑 pass def execute(self): logger.info(f任务 [{self.name}] 开始执行) try: result self.run() logger.info(f任务 [{self.name}] 执行完成结果: {result}) return result except Exception as e: logger.error(f任务 [{self.name}] 执行失败原因: {e}) raise子类只需要实现run方法异常捕获和日志记录统一由基类完成。3.4 调度模块使用 APScheduler 实现定时任务调度。常见的场景有两种每天早上固定时间执行每日签到任务。每隔一段时间执行一次检查任务。# core/scheduler.py from apscheduler.schedulers.blocking import BlockingScheduler from apscheduler.triggers.cron import CronTrigger from apscheduler.triggers.interval import IntervalTrigger def create_scheduler(): scheduler BlockingScheduler(timezoneAsia/Shanghai) return scheduler def add_cron_job(scheduler, func, hour, minute, job_id): scheduler.add_job( func, triggerCronTrigger(hourhour, minuteminute, timezoneAsia/Shanghai), idjob_id, replace_existingTrue, ) def add_interval_job(scheduler, func, minutes, job_id): scheduler.add_job( func, triggerIntervalTrigger(minutesminutes, timezoneAsia/Shanghai), idjob_id, replace_existingTrue, )使用 Cron 触发器可以精确控制每天几点执行使用 Interval 触发器可以控制周期循环任务。3.5 日志模块日志是自动化任务最重要的观测手段。建议使用loguru配置简洁输出清晰# core/logger.py import sys from loguru import logger def setup_logger(): logger.remove() logger.add( sys.stderr, levelINFO, formatgreen{time:YYYY-MM-DD HH:mm:ss}/green | level{level}/level | {message} ) logger.add( logs/robot_{time:YYYY-MM-DD}.log, rotation00:00, retention30 days, levelINFO, encodingutf-8 ) return logger日志文件按天切割保留 30 天方便回顾每天任务执行情况。4. 完整实战案例搭建一个简单的 B 站每日任务机器人下面的案例覆盖从配置读取、请求封装到任务定义、定时调度的完整闭环。这里以两个常见任务为例获取账号登录状态。模拟每日签到操作。实际接口以你抓包得到的地址为准重点是理解集成方式。4.1 创建项目结构按前面设计的目录结构创建项目mkdir robotbilibili cd robotbilibili mkdir core tasks utils logs touch main.py config.py requirement.txt touch core/__init__.py core/http_client.py core/scheduler.py core/logger.py touch tasks/__init__.py tasks/base_task.py tasks/sign_task.py tasks/user_task.py touch utils/__init__.py utils/cookie_utils.py4.2 编写配置文件先创建依赖清单# requirement.txt requests2.28.0 APScheduler3.9.0 python-dotenv1.0.0 loguru0.7.0安装依赖pip install -r requirement.txt创建.env文件BILI_COOKIE你的Cookie BILI_UAMozilla/5.04.3 编写核心代码4.3.1 HTTP 客户端# core/http_client.py import time import requests from loguru import logger from config import Config class HttpClient: def __init__(self): self.session requests.Session() self.session.headers.update({ User-Agent: Config.UA, Referer: https://www.bilibili.com/, Origin: https://www.bilibili.com, Cookie: Config.COOKIE, }) self.timeout 10 def get_json(self, url, paramsNone): return self._request(GET, url, paramsparams) def post_json(self, url, dataNone): return self._request(POST, url, datadata) def _request(self, method, url, paramsNone, dataNone): for attempt in range(1, Config.RETRY_TIMES 1): try: response self.session.request( method, url, paramsparams, datadata, timeoutself.timeout, ) response.raise_for_status() json_data response.json() return json_data except (requests.exceptions.RequestException, ValueError) as e: logger.warning(f请求失败: {url}第 {attempt} 次重试原因: {e}) if attempt Config.RETRY_TIMES: raise time.sleep(attempt * 2)4.3.2 任务基类# tasks/base_task.py from abc import ABC, abstractmethod from loguru import logger class BaseTask(ABC): name base_task def __init__(self, client): self.client client abstractmethod def run(self): pass def execute(self): logger.info(f任务 [{self.name}] 开始执行) try: result self.run() logger.info(f任务 [{self.name}] 执行完成) return result except Exception as e: logger.error(f任务 [{self.name}] 执行失败原因: {e}) raise4.3.3 用户信息任务这个任务用来验证 Cookie 是否有效获取当前登录用户的基础信息# tasks/user_task.py from tasks.base_task import BaseTask class UserInfoTask(BaseTask): name 查询用户信息 def run(self): url https://api.bilibili.com/x/web-interface/nav json_data self.client.get_json(url) if json_data.get(code) 0: data json_data.get(data, {}) username data.get(uname) is_login data.get(isLogin) return {username: username, is_login: is_login} return {error: json_data.get(message, 未知错误)}4.3.4 每日签到任务签到类任务的通用逻辑是请求签到接口。判断返回状态码。记录结果。# tasks/sign_task.py from tasks.base_task import BaseTask from loguru import logger class DailySignTask(BaseTask): 每日签到任务。 注意B 站不同活动的签到接口地址不同需要根据实际使用的功能来配置。 这里用一个占位接口演示完整的任务类写法。 name 每日签到 def run(self): url https://api.bilibili.com/x/web-interface/签到接口占位 json_data self.client.post_json(url) code json_data.get(code, -1) if code 0: logger.success(签到成功) return {success: True, message: 签到成功} # 已经签到过,通常返回特定错误码 if code -101: logger.warning(账号未登录请检查 Cookie 是否有效) return {success: False, message: 账号未登录} if 重复 in json_data.get(message, ): logger.info(今日已经签到无需重复操作) return {success: True, message: 今天已签到} logger.error(f签到失败: {json_data}) return {success: False, message: json_data.get(message)}这里使用占位地址原因在于 B 站多个功能点都有独立的签到接口不同账号开放状态也不同。你在实际使用时可以打开浏览器开发者工具切换到 Network 面板执行一次对应的签到操作然后找到对应的请求地址替换到代码中即可。4.4 编写主入口# main.py from core.http_client import HttpClient from core.logger import setup_logger from core.scheduler import create_scheduler, add_cron_job from tasks.user_task import UserInfoTask from tasks.sign_task import DailySignTask def daily_job(): client HttpClient() user_task UserInfoTask(client) login_info user_task.execute() print(f当前登录用户: {login_info}) sign_task DailySignTask(client) sign_result sign_task.execute() print(f签到结果: {sign_result}) def main(): setup_logger() scheduler create_scheduler() # 每天早上 9:00 执行每日任务 add_cron_job(scheduler, daily_job, hour9, minute0, job_iddaily_task) print(机器人已启动等待定时任务触发...) # 启动前立即执行一次方便调试 daily_job() scheduler.start() if __name__ __main__: main()4.5 运行与验证在项目根目录运行python main.py预期效果日志显示机器人启动。先立刻执行一次 daily_job。输出用户信息确认 Cookie 是否有效。输出签到任务执行结果。定时器进入监听状态到每天早上 9 点自动执行。这种“启动先执行一次 定时执行”的方式非常适合调试避免写完之后还要等第二天才能看到运行效果。5. 常见问题与排查思路5.1 Cookie 失效问题现象常见原因解决思路接口返回 -101Cookie 过期或被服务器端踢下线使用浏览器重新登录并更新 Cookie接口返回 412请求频率过高或 User-Agent 不完整降低请求频率补全请求头接口返回 -352风控校验失败暂停操作改用更真实的请求头延长任务间隔怎么避免 Cookie 频繁失效不要在多台设备或不同 IP 环境下频繁切换登录。避免机器人高频操作。在本地保存最近一次有效的 Cookie发现失效时给出提醒。可以将 Cookie 的获取做成半自动每次需要更新时打印提示手动更新.env。5.2 请求频控和风控B 站对接口请求有频率限制。短时间内大量请求容易触发风控表现是突然返回 412。部分接口需要验证码。账号被临时限制登录。核心建议每个任务之间增加随机延时。总请求频率控制在一分钟个位数以内。不要用多线程或异步并发大量请求。不要对同一个接口在短时间内做重复无效请求。增加随机延时的示例import random import time def random_delay(min_seconds1, max_seconds5): delay random.uniform(min_seconds, max_seconds) time.sleep(delay)5.3 接口地址变更B 站经常调整接口或字段。遇到以下情况时大部分是接口地址变化导致的返回结构不完整。原来可用的 code 码含义发生变化。请求参数提示缺失。排查步骤用浏览器手动执行一次对应操作。打开开发者工具 Network找到真正发起的请求。对比请求地址、请求方法、请求参数。更新代码中的 URL 和参数。这属于正常维护流程做机器人项目时要预留这种接口适配成本。5.4 定时任务没执行APScheduler 任务时区必须正确设置。操作系统的时区和定时任务配置的时区不一致可能导致执行时间偏移。建议在创建调度器时明确指定时区scheduler BlockingScheduler(timezoneAsia/Shanghai)如果使用 Docker 部署还要确认容器内的时区是否正确设置为 Asia/Shanghai。5.5 常见的登录状态判断错误判断登录状态最稳定的是调用用户信息接口不要依赖某个单一签到接口的返回值。正确逻辑是nav_url https://api.bilibili.com/x/web-interface/nav data client.get_json(nav_url) if data.get(code) 0 and data.get(data, {}).get(isLogin): print(已登录) else: print(未登录)6. 最佳实践与工程建议6.1 配置管理不要把 Cookie 写死在代码里。推荐使用环境变量或.env文件管理配置。# config.py import os from dotenv import load_dotenv load_dotenv() class Config: BILI_COOKIE os.getenv(BILI_COOKIE, ) BILI_UA os.getenv(BILI_UA, ) RETRY_TIMES int(os.getenv(RETRY_TIMES, 3)) REQUEST_TIMEOUT int(os.getenv(REQUEST_TIMEOUT, 10))使用场景本地开发.env文件提供配置。服务器部署通过环境变量注入。多人协作只提交.env.example模板不提交真实.env。6.2 异常处理不要用一层try...except包裹所有逻辑。更合理的思路是请求层处理网络异常和超时。任务层处理业务异常。调度层记录任务级异常。def safe_execute(task): try: return task.execute() except Exception as e: # 在任务外层捕获避免单个任务失败拖垮整个调度器 logger.exception(f任务 {task.name} 异常: {e}) return None这样即使某个任务失败其他任务仍然可以继续执行。6.3 日志记录日志至少需要包含以下信息任务名称。请求的接口地址。返回状态码。请求耗时。异常堆栈。import time from loguru import logger start_time time.time() result client.get_json(url) cost_time time.time() - start_time logger.info(f请求 {url} 耗时 {cost_time:.2f}s, 返回码 {result.get(code)})6.4 安全边界账号安全不要随意在公开仓库提交 Cookie。不要在不受信任的第三方程序中输入 B 站账号密码。不要使用扫码登录逻辑中保存的长期凭证做超出个人用途的事。合法合规机器人只应用于自己账号的日常任务管理。避免自动化操作影响平台正常运营。遇到验证码、风控提示时应立即停止自动化并人工处理而不是使用破解手段绕过。6.5 可维护性任务模块化新增任务时在 tasks 目录下创建新的任务文件继承 BaseTask 并实现 run 方法。之后在主入口中注册到调度器即可。接口封装与业务分离core 层只处理通用请求逻辑tasks 层只写业务参数和结果校验避免把接口细节散落在各处。数据持久化如果任务需要记录历史执行结果可以设计一个简单的 JSON 文件存储模块import json import os from datetime import datetime def save_result(task_name, data): record { task: task_name, time: datetime.now().strftime(%Y-%m-%d %H:%M:%S), data: data, } filepath logs/task_history.json history [] if os.path.exists(filepath): with open(filepath, r, encodingutf-8) as f: history json.load(f) history.append(record) with open(filepath, w, encodingutf-8) as f: json.dump(history, f, ensure_asciiFalse, indent2)6.6 性能优化复用 requests.Session不要每个任务都实例化一次客户端。使用连接池减少 TCP 握手开销。避免在同一任务中串行请求大量接口。批量操作拆分为小批次并在请求之间添加延时。6.7 部署到服务器如果希望机器人 24 小时运行可以部署到云服务器。推荐方案nohup python main.py logs/console.log 21 更稳定的方式是使用 systemd 托管进程日志管理交给系统。systemd 服务文件示例[Unit] Descriptionrobotbilibili service Afternetwork.target [Service] WorkingDirectory/path/to/robotbilibili ExecStart/usr/bin/python3 /path/to/robotbilibili/main.py Restartalways RestartSec10 [Install] WantedBymulti-user.target7. 总结与学习路线robotbilibili 这类项目的核心价值在于理解 HTTP 请求封装、定时任务调度、异常处理和日志管理。本文从项目背景讲起设计了一个清晰的分层结构实现了请求客户端、任务基类、调度模块和日志模块并提供了一个可以运行的最小每日任务示例。如果你想继续深入可以从下面几个方向入手研究更多 B 站任务接口在合规前提下扩展任务维度。增加 Web 管理面板通过浏览器查看任务执行情况。使用 Redis 保存任务状态实现多账号管理。引入消息队列将任务执行和结果上报解耦。学习抓包工具和接口分析提高接口适配速度。实际开发中最需要关注的是接口变化和风控策略。建议把接口请求单独封装成适配层减少接口变更时对业务代码的冲击。同时保持最小请求频率在自动化效率和账号安全之间找到平衡。动手写一个属于自己的机器人框架比直接使用现成脚本更能锻炼工程能力。你可以从最简单的“每日签到”开始然后逐步加入新的任务模块把 robotbilibili 扩展成适合自己的效率工具。遇到问题时结合日志和接口返回信息逐步排查这也是最有价值的实践过程。
返回列表