好友
阅读权限 10
听众
最后登录 1970-1-1
君临天下v
发表于 2020-7-21 18:58
本帖最后由 君临天下v 于 2020-8-22 23:06 编辑
2020/08/22更新
更新内容
1.增加参与B站官方活动抽奖的功能
活动列表在config/activity.json文件中,对应B站 https://www.bilibili.com/blackboard/x/act_list/ ,我抽中了一个抱枕,奖品一般是几个硬币或者月度会员之类的。(所有活动都有过期时间,如果出新活动需要手动更新config/activity.json文件)。
2.增加动态清理的功能,每半个月清理一次转发的抽奖动态和被原up主删除的失效动态
3.去除客户端access_key参数
模拟客户端签到的功能不再需要手机抓包得到access_key,账户配置文件移到config/config.json
4.添加aliyun-serverless-template.yml文件,借助阿里云的funcraft工具可实现一键部署到阿里云
阿里云funcraft工具windows版下载地址 https://gosspublic.alicdn.com/fun/fun-v3.6.14-win.exe.zip , 解压进入cmd,cd到解压目录,执行fun-v3.6.14-win config,输入阿里云的AccountID,AccessKeyID,AccessKeySecret和服务器地区四个参数,再cd到我的脚本目录,执行fun-v3.6.14-win deploy -t aliyun-serverless-template.yml即可直接部署到阿里云函数。
</br>
最新代码已经上传到附件和github(https://github.com/happy888888/BiliExp ) ,支持使用github actions将代码自动部署到阿里云函数(需要将阿里云的AccessKey等参数和B站cookie等参数填入github中的Secret中),其他云函数目前并不支持一键部署,请自行探索手动部署</br>
今天开放注册,新人报道,分享自己写的B站自动操作脚本,功能简介如下:
1.投币、点赞、分享视频(每项操作都有经验值,如果今天已投币大于5,则不投币,否则投x个币,x为现有币的数量)
2.直播签到(连续签到可以获得银瓜子,大老爷权限和月老称号)
3.自动转发抽奖(计划任务每隔10分钟启动一次抽奖脚本)
4.漫画APP签到(连续签到7天可以获得漫读券一张)
Biliapi.py,B站操作类,后续脚本依赖这个类
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
import requests
import json
import re
class Biliapi(object):
"B站API操作"
__headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36",
"Referer": "https://www.bilibili.com/",
}
def __init__(self, cookieData):
#创建session
self.__session = requests.session()
#添加cookie
requests.utils.add_dict_to_cookiejar(self.__session.cookies, cookieData)
#设置header
self.__session.headers.update(Biliapi.__headers)
self.__bili_jct = cookieData["bili_jct"]
self.__uid = cookieData["DedeUserID"]
content = self.__session.get("https://account.bilibili.com/home/reward")
if json.loads(content.text)["code"] != 0:
raise Exception("参数验证失败")
def getReward(self):
"取B站经验信息"
url = "https://account.bilibili.com/home/reward"
content = self.__session.get(url)
return json.loads(content.text)["data"]
@staticmethod
def getId(url):
"取B站指定视频链接的aid和cid号"
content = requests.get(url, headers=Biliapi.__headers)
match = re.search( 'https:\/\/www.bilibili.com\/video\/av(.*?)\/\">', content.text, 0)
aid = match.group(1)
match = re.search( '\"cid\":(.*?),', content.text, 0)
cid = match.group(1)
return {"aid": aid, "cid": cid}
def getCoin(self):
"获取剩余硬币数"
url = "https://api.bilibili.com/x/web-interface/nav?build=0&mobi_app=web"
content = self.__session.get(url)
return int(json.loads(content.text)["data"]["money"])
def coin(self, aid, num, select_like):
"给指定av号视频投币"
url = "https://api.bilibili.com/x/web-interface/coin/add"
post_data = {
"aid": aid,
"multiply": num,
"select_like": select_like,
"cross_domain": "true",
"csrf": self.__bili_jct
}
content = self.__session.post(url, post_data)
return json.loads(content.text)
def share(self, aid):
"分享指定av号视频"
url = "https://api.bilibili.com/x/web-interface/share/add"
post_data = {
"aid": aid,
"csrf": self.__bili_jct
}
content = self.__session.post(url, post_data)
return json.loads(content.text)
def report(self, aid, cid, progres):
"B站上报观看进度"
url = "http://api.bilibili.com/x/v2/history/report"
post_data = {
"aid": aid,
"cid": cid,
"progres": progres,
"csrf": self.__bili_jct
}
content = self.__session.post(url, post_data)
return json.loads(content.text)
def getHomePageUrls(self):
"取B站首页推荐视频地址列表"
url = "https://www.bilibili.com"
content = self.__session.get(url)
match = re.findall( '<div class=\"info-box\"><a href=\"(.*?)\" target=\"_blank\">', content.text, 0)
match = ["https:" + x for x in match]
return match
@staticmethod
def getRegions(rid=1, num=6):
"获取B站分区视频信息"
url = "https://api.bilibili.com/x/web-interface/dynamic/region?ps=" + str(num) + "&rid=" + str(rid)
content = requests.get(url, headers=Biliapi.__headers)
datas = json.loads(content.text)["data"]["archives"]
ids = []
for x in datas:
ids.append({"title": x["title"], "aid": x["aid"], "bvid": x["bvid"], "cid": x["cid"]})
return ids
@staticmethod
def getRankings(rid=1, day=3):
"获取B站分区排行榜视频信息"
url = "https://api.bilibili.com/x/web-interface/ranking?rid=" + str(rid) + "&day=" + str(day)
content = requests.get(url, headers=Biliapi.__headers)
datas = json.loads(content.text)["data"]["list"]
ids = []
for x in datas:
ids.append({"title": x["title"], "aid": x["aid"], "bvid": x["bvid"], "cid": x["cid"], "coins": x["coins"], "play": x["play"]})
return ids
def repost(self, dynamic_id, content="", extension='{"emoji_type":1}'):
"转发B站动态"
url = "https://api.vc.bilibili.com/dynamic_repost/v1/dynamic_repost/repost"
post_data = {
"uid": self.__uid,
"dynamic_id": dynamic_id,
"content": content,
"extension": extension,
#"at_uids": "",
#"ctrl": "[]",
"csrf_token": self.__bili_jct
}
content = self.__session.post(url, post_data)
return json.loads(content.text)
def getDynamicNew(self, type_list='268435455'):
"取B站用户动态数据"
url = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=" + self.__uid + "&type_list=" + type_list
content = self.__session.get(url)
return json.loads(content.text)
@staticmethod
def mangaClockIn(access_key, platform="android"):
"模拟B站漫画客户端签到"
url = "https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn"
headers = {
"User-Agent": "Mozilla/5.0 BiliComic/3.0.0",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
}
post_data = {
"access_key": access_key,
"platform": platform
}
content = requests.post(url, data=post_data, headers=headers)
return json.loads(content.text)
def xliveSign(self):
"B站直播签到"
url = "https://api.live.bilibili.com/xlive/web-ucenter/v1/sign/DoSign"
content = self.__session.get(url)
return json.loads(content.text)
BiliExp.py,负责直播签到,投币分享获取经验,模拟观看视频用来模拟用户登陆操作
[Python] 纯文本查看 复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from Biliapi import Biliapi
import logging
cookieDatas = [{
"SESSDATA": "填写账户1 SESSDATA",
"bili_jct": "填写账户1 bili_jct",
"DedeUserID": "填写账户1 UserID",
},
{
"SESSDATA": "填写账户2 SESSDATA",
"bili_jct": "填写账户2 bili_jct",
"DedeUserID": "填写账户2 UserID",
}]
def bili_exp(cookieData):
"B站直播签到,投币分享获取经验,模拟观看一个视频"
logging.info(f': B站经验脚本开始为id为{cookieData["DedeUserID"]}的用户进行直播签到,投币点赞分享并观看一个首页视频')
try:
biliapi = Biliapi(cookieData)
except Exception as e:
logging.error(f'登录验证id为{cookieData["DedeUserID"]}的账户失败,原因为{str(e)},跳过此账户后续所有操作')
return
try:
xliveInfo = biliapi.xliveSign()
logging.info(f'bilibili直播签到信息:{str(xliveInfo)}')
except Exception as e:
logging.warning(f'直播签到异常,原因为{str(e)}')
try:
reward = biliapi.getReward()
logging.info(f'经验脚本开始前经验信息 :{str(reward)}')
except Exception as e:
logging.warning(f'获取账户经验信息异常,原因为{str(e)},跳过此账户后续所有操作')
return
try:
coin_num = biliapi.getCoin()
except Exception as e:
logging.warning(f'获取账户剩余硬币数异常,原因为{str(e)}')
coin_num = 0
coin_exp_num = (50 - reward["coins_av"]) // 10
toubi_num = coin_exp_num if coin_num > coin_exp_num else coin_num
try:
datas = biliapi.getRegions()
except Exception as e:
logging.warning(f'获取B站分区视频信息异常,原因为{str(e)},跳过此账户后续所有操作')
return
if(toubi_num > 0):
for i in range(toubi_num):
try:
info = biliapi.coin(datas[i]["aid"], 1, 1)
logging.info(f'投币信息 :{str(info)}')
except Exception as e:
logging.warning(f'投币异常,原因为{str(e)}')
try:
info = biliapi.report(datas[5]["aid"], datas[5]["cid"], 300)
logging.info(f'模拟视频观看进度上报:{str(info)}')
except Exception as e:
logging.warning(f'模拟视频观看异常,原因为{str(e)}')
try:
info = biliapi.share(datas[5]["aid"])
logging.info(f'分享视频结果:{str(info)}')
except Exception as e:
logging.warning(f'分享视频异常,原因为{str(e)}')
logging.info(f'id为{cookieData["DedeUserID"]}的账户操作全部完成')
def main(*args):
try:
logging.basicConfig(filename="exp.log", filemode='a', level=logging.INFO, format="%(asctime)s: %(levelname)s, %(message)s", datefmt="%Y/%d/%m %H:%M:%S")
except:
pass
for x in cookieDatas:
bili_exp(x)
main()
需要填写SESSDATA,bili_jct,DedeUserID三个参数,支持多用户,参数获取方法为:
浏览器打开B站主页--》按F12打开开发者工具--》application--》cookies
BiliLottery.py,负责转发抽奖信息,需要定时启动
[Python] 纯文本查看 复制代码
from Biliapi import Biliapi
import sqlite3
cookieData = {
"SESSDATA": "0ad8e6d8%2C1608434698%2C1eba3*61",
"bili_jct": "e85bbbe9712cf8b9160aa5921a269a97",
"DedeUserID": "8466742",
}
def update(dynamic_id):
conn = sqlite3.connect('lottery.db')
cursor = conn.cursor()
cursor.execute("SELECT id FROM lottery WHERE dynamic_id=?", (dynamic_id,))
result = True if cursor.fetchone() else False
if not result:
cursor.execute("SELECT id FROM lottery ORDER BY date ASC LIMIT 0,1")
id = cursor.fetchone()[0]
cursor.execute("UPDATE lottery SET dynamic_id=? WHERE id=?", (dynamic_id, id))
cursor.close()
conn.commit()
conn.close()
return result
def bili_lottery(data):
try:
biliapi = Biliapi(data)
except Exception as e:
logging.error(f'登录验证id为{data["DedeUserID"]}的账户失败,原因为{str(e)},跳过后续所有操作')
return
try:
datas = biliapi.getDynamicNew()["data"]["cards"]
except Exception as e:
logging.warning(f'获取动态列表异常,原因为{str(e)},跳过后续所有操作')
return
for x in datas:
if x.__contains__("extension") and x["extension"].__contains__("lott"):
uname = x["desc"]["user_profile"]["info"]["uname"]
dynamic_id = x["desc"]["dynamic_id"]
if not update(dynamic_id):
try:
biliapi.repost(dynamic_id)
logging.info(f'转发抽奖(用户名:{uname},dynamic_id:{str(dynamic_id)})成功')
except Exception as e:
logging.warning(f'此次转发抽奖失败,原因为{str(e)}')
def main(*args):
try:
logging.basicConfig(filename="lottery.log", filemode='a', level=logging.INFO, format="%(asctime)s: %(levelname)s, %(message)s", datefmt="%Y/%d/%m %H:%M:%S")
except:
pass
bili_lottery(cookieData)
main()
mangaClockIn.py,负责B站漫画APP签到,需要access_key参数来保持登录状态,需要会手机抓包的才能拿到这个参数,我这里就不细讲了
[Python] 纯文本查看 复制代码
from Biliapi import Biliapi
import logging
access_keys = ["这里填写access_key,可以多个,用逗号分开"]
def mangaClockIn(access_key):
logging.info(f'B站漫画签到脚本开始为access_key({access_key}的账户签到')
try:
result = Biliapi.mangaClockIn(access_key)
logging.info(f'签到信息为:{str(result)}')
except Exception as e:
logging.warning(f'签到异常,原因为{str(e)}')
def main(*args):
try:
logging.basicConfig(filename="manga.log", filemode='a', level=logging.INFO, format="%(asctime)s: %(levelname)s, %(message)s", datefmt="%Y/%d/%m %H:%M:%S")
except:
pass
for x in access_keys:
mangaClockIn(x)
main()
所有脚本放在附件里,除了抽奖的脚本都可以在腾讯云函数里面运行,腾讯云函数怎么用论坛里已经有教程了,这里不细讲了。
BiliExp.zip
16.64 KB, 下载次数: 797, 下载积分: 吾爱币 -1 CB
B站自动操作脚本(阿里云函数版)
免费评分
查看全部评分