首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >哔哩哔哩自动发布工具,bilibili自动上传发帖软件,python版本源码~~~

哔哩哔哩自动发布工具,bilibili自动上传发帖软件,python版本源码~~~

原创
作者头像
用户11719788
发布2025-07-13 19:45:27
发布2025-07-13 19:45:27
5000
举报

成品下载地址:https://www.pan38.com/yun/share.php?code=JCnzE 提取密码:1135

这个B站自动发布工具包含视频上传、动态发布和评论功能,使用Selenium实现登录和视频上传,requests处理API请求。使用时需要安装selenium和requests库,并配置ChromeDriver。

源码部分:

代码语言:txt
复制

import os
import time
import json
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from datetime import datetime

class BilibiliAutoUploader:
    def __init__(self, config_file='config.json'):
        self.config = self._load_config(config_file)
        self.driver = None
        self.cookies = None
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
            'Referer': 'https://www.bilibili.com/'
        }
        
    def _load_config(self, config_file):
        with open(config_file, 'r', encoding='utf-8') as f:
            return json.load(f)
    
    def login(self):
        options = webdriver.ChromeOptions()
        options.add_argument('--disable-gpu')
        options.add_argument('--no-sandbox')
        options.add_argument('--disable-dev-shm-usage')
        
        self.driver = webdriver.Chrome(options=options)
        self.driver.get('https://passport.bilibili.com/login')
        
        # 等待登录页面加载
        WebDriverWait(self.driver, 30).until(
            EC.presence_of_element_located((By.ID, 'login-username'))
        )
        
        # 输入用户名密码
        username = self.driver.find_element(By.ID, 'login-username')
        password = self.driver.find_element(By.ID, 'login-passwd')
        
        username.send_keys(self.config['username'])
        password.send_keys(self.config['password'])
        
        # 点击登录按钮
        login_button = self.driver.find_element(By.CLASS_NAME, 'btn-login')
        login_button.click()
        
        # 等待登录完成
        WebDriverWait(self.driver, 30).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'header-avatar'))
        )
        
        # 获取cookies
        self.cookies = {cookie['name']: cookie['value'] for cookie in self.driver.get_cookies()}
        
    def upload_video(self, video_path, title, desc, tags, cover_path=None):
        if not os.path.exists(video_path):
            raise FileNotFoundError(f"视频文件 {video_path} 不存在")
            
        if cover_path and not os.path.exists(cover_path):
            raise FileNotFoundError(f"封面文件 {cover_path} 不存在")
            
        self.driver.get('https://member.bilibili.com/platform/upload/video/frame')
        
        # 等待上传页面加载
        WebDriverWait(self.driver, 30).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'upload-btn'))
        )
        
        # 上传视频文件
        upload_input = self.driver.find_element(By.CLASS_NAME, 'upload-btn').find_element(By.TAG_NAME, 'input')
        upload_input.send_keys(os.path.abspath(video_path))
        
        # 等待视频上传完成
        WebDriverWait(self.driver, 600).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'video-title'))
        )
        
        # 填写视频信息
        title_input = self.driver.find_element(By.CLASS_NAME, 'video-title')
        title_input.clear()
        title_input.send_keys(title)
        
        desc_input = self.driver.find_element(By.CLASS_NAME, 'video-desc')
        desc_input.clear()
        desc_input.send_keys(desc)
        
        # 上传封面
        if cover_path:
            cover_input = self.driver.find_element(By.CLASS_NAME, 'cover-upload-btn').find_element(By.TAG_NAME, 'input')
            cover_input.send_keys(os.path.abspath(cover_path))
            time.sleep(3)  # 等待封面处理完成
            
        # 添加标签
        tag_input = self.driver.find_element(By.CLASS_NAME, 'tag-input')
        for tag in tags:
            tag_input.send_keys(tag)
            tag_input.send_keys(Keys.ENTER)
            time.sleep(0.5)
            
        # 选择分区
        self._select_category()
        
        # 提交视频
        submit_button = self.driver.find_element(By.CLASS_NAME, 'submit-btn')
        submit_button.click()
        
        # 等待提交完成
        WebDriverWait(self.driver, 30).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'success-info'))
        )
        
        # 获取视频aid
        success_info = self.driver.find_element(By.CLASS_NAME, 'success-info').text
        aid = success_info.split('av')[1].split(')')[0]
        
        return aid
    
    def _select_category(self):
        # 点击分区选择按钮
        category_btn = self.driver.find_element(By.CLASS_NAME, 'category-btn')
        category_btn.click()
        
        # 等待分区选择框出现
        WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'category-select'))
        )
        
        # 选择分区 (这里选择"生活"分区)
        first_level = self.driver.find_elements(By.CLASS_NAME, 'first-level')[3]  # 生活分区
        first_level.click()
        
        second_level = first_level.find_elements(By.CLASS_NAME, 'second-level')[0]  # 日常分区
        second_level.click()
        
        # 确认选择
        confirm_btn = self.driver.find_element(By.CLASS_NAME, 'confirm-btn')
        confirm_btn.click()
        
    def post_dynamic(self, content, pictures=None):
        if not self.cookies:
            raise Exception("请先登录")
            
        url = 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/create'
        data = {
            'dynamic_id': 0,
            'type': 4,
            'content': content,
            'csrf': self.cookies.get('bili_jct')
        }
        
        # 处理图片
        if pictures:
            pic_urls = []
            for pic in pictures:
                upload_url = 'https://api.vc.bilibili.com/api/v1/drawImage/upload'
                files = {'file_up': open(pic, 'rb')}
                headers = {
                    'cookie': '; '.join([f"{k}={v}" for k, v in self.cookies.items()]),
                    **self.headers
                }
                resp = requests.post(upload_url, files=files, headers=headers)
                if resp.status_code == 200:
                    pic_urls.append(resp.json()['data']['image_url'])
                    
            if pic_urls:
                data['pictures'] = json.dumps(pic_urls)
                data['type'] = 2  # 带图片的动态
        
        headers = {
            'cookie': '; '.join([f"{k}={v}" for k, v in self.cookies.items()]),
            **self.headers
        }
        
        resp = requests.post(url, data=data, headers=headers)
        if resp.status_code == 200 and resp.json()['code'] == 0:
            return resp.json()['data']['dynamic_id']
        else:
            raise Exception(f"发布动态失败: {resp.text}")
            
    def comment_video(self, aid, content):
        if not self.cookies:
            raise Exception("请先登录")
            
        url = 'https://api.bilibili.com/x/v2/reply/add'
        data = {
            'oid': aid,
            'type': 1,
            'message': content,
            'csrf': self.cookies.get('bili_jct')
        }
        
        headers = {
            'cookie': '; '.join([f"{k}={v}" for k, v in self.cookies.items()]),
            **self.headers
        }
        
        resp = requests.post(url, data=data, headers=headers)
        if resp.status_code == 200 and resp.json()['code'] == 0:
            return resp.json()['data']['rpid']
        else:
            raise Exception(f"评论失败: {resp.text}")
            
    def close(self):
        if self.driver:
            self.driver.quit()
            
    def __enter__(self):
        return self
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
代码语言:txt
复制
from bilibili_auto_uploader import BilibiliAutoUploader
import time

def main():
    with BilibiliAutoUploader() as uploader:
        # 登录
        uploader.login()
        
        # 上传视频
        video_path = 'my_video.mp4'
        title = '我的日常vlog - ' + time.strftime("%Y年%m月%d日")
        desc = '这是我的日常vlog,记录生活中的点点滴滴'
        tags = ['vlog', '日常', '生活记录']
        cover_path = 'cover.jpg'
        
        aid = uploader.upload_video(video_path, title, desc, tags, cover_path)
        print(f"视频上传成功,aid: {aid}")
        
        # 发布动态
        dynamic_content = f"新视频发布啦!{title} #vlog #日常"
        dynamic_pics = ['screenshot1.jpg', 'screenshot2.jpg']
        dynamic_id = uploader.post_dynamic(dynamic_content, dynamic_pics)
        print(f"动态发布成功,dynamic_id: {dynamic_id}")
        
        # 评论视频
        comment_content = "欢迎大家观看我的视频,喜欢的话请一键三连哦~"
        rpid = uploader.comment_video(aid, comment_content)
        print(f"评论成功,rpid: {rpid}")

if __name__ == '__main__':
    main()

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档