h3V4Kh

B站自动操作脚本,功能简介如下:
1.投币、点赞、分享视频(每项操作都有经验值,如果今天已投币大于5,则不投币,否则投x个币,x为现有币的数量)
2.直播签到(连续签到可以获得银瓜子,大老爷权限和月老称号)
3.自动转发抽奖(计划任务每隔10分钟启动一次抽奖脚本)
4.漫画APP签到(连续签到7天可以获得漫读券一张)

Biliapi.py

Biliapi.py,B站操作类,后续脚本依赖这个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# -*- 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

BiliExp.py,负责直播签到,投币分享获取经验,模拟观看视频用来模拟用户登陆操作

需要填写SESSDATA,bili_jct,DedeUserID三个参数,支持多用户,参数获取方法为:
浏览器打开B站主页–》按F12打开开发者工具–》application–》cookies

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/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()

BiliLottery.py

BiliLottery.py,负责转发抽奖信息,需要定时启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
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)

mangaClockIn.py

mangaClockIn.py,负责B站漫画APP签到,需要access_key参数来保持登录状态,需要会手机抓包的才能拿到这个参数,我这里就不细讲了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
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()

P.S.

所有脚本放在附件里,除了抽奖的脚本都可以在腾讯云函数里面运行,腾讯云函数怎么用度娘里已经有很多教程了,这里不细讲了。

附件:biliexp.zip

2xhjlt