B站协议登录、点赞、收藏、转发实现及代码
关注、动态转发实现动态抽奖实现及代码
直播预约抽奖实现及代码
本文为本专栏的总结文章
一、扫码登录
请求获取二维码包,得到二维码链接和qrcode_key参数之后,利用qrcode_key循环GET请求登录状态包即可,扫码成功时的响应中还会有一个URL和Cookie,只需要带Cookie访问这个URL即可成功登录
详细分析请看以下文章
B站扫码登录协议
获取二维码包
get请求
https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-fe-header&go_url=https://www.bilibili.com/
登录状态包
get请求
https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=e4bc73831b372f8fcd2a1e35e67ff981&source=main-fe-header
未扫码
已扫码未确认
登录成功
实现代码
def login_account(index):
url = 'https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main_web&go_url=https://space.bilibili.com&web_location=333.1228'
response, cookies = get_url(url)
if response:
qrcode_url = response['data']['url']
qrcode_key = response['data']['qrcode_key']
print(f'QR Code URL: {qrcode_url}')
print(f'QR Code Key: {qrcode_key}')
print(f'Cookies: {cookies}')
# 生成二维码并保存为图片文件
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(qrcode_url)
qr.make(fit=True)
img = qr.make_image(fill='black', back_color='white')
qrcode_filename = f"qrcode_{index}.png"
img.save(qrcode_filename) # 保存二维码图片到文件
print(f"二维码已生成并保存为 {qrcode_filename}")
# 启动线程每隔5秒获取一次二维码状态
polling_thread = threading.Thread(target=poll_qrcode_status, args=(qrcode_key, index))
polling_thread.start()
else:
print("未能获取二维码信息")
def poll_qrcode_status(qrcode_key, index):
while True:
try:
print(f"开始获取二维码状态,index: {index}")
poll_url = f"https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={qrcode_key}&source=navUserCenterLogin"
print(f"Poll URL: {poll_url}")
response, cookies = get_url(poll_url)
print("二维码状态响应:")
print(response)
if response and 'data' in response and response['data'].get('url'):
print(f"登录成功,跳转URL: {response['data']['url']}")
login_response, login_cookies = get_url(response['data']['url'])
print(f"登录后Cookies: {login_cookies}")
cookie_string = save_cookies_as_string(login_cookies)
dedeuserid = login_cookies.get("DedeUserID", "Unknown")
bili_jct = login_cookies.get("bili_jct", "Unknown")
login_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
save_login_data(dedeuserid, bili_jct, cookie_string, "1", login_time)
print(f"登录数据已保存到 {csv_file}")
# 执行deal_data.py
#subprocess.run(["python", "deal_data.py"])
break
except Exception as e:
print(f"获取二维码状态时出错, index: {index}, 错误: {e}")
time.sleep(5) # 每隔5秒获取一次状态
二、视频点赞|投币|收藏实现
获取收藏的aid,再通过Cookie以及Cookie中的csrf参数即可实现这三个功能
详细分析请看以下文章
b站视频点赞收藏投币协议实现
2.1点赞包
POST请求 https://api.bilibili.com/x/web-interface/archive/like
原始表单数据aid=113173461999500&like=1&eab_x=1&ramval=7&source=web_normal&ga=1&csrf=46378a87cb7283a133e9c32b9c09bee7
2.2收藏
POST 请求 https://api.bilibili.com/x/v3/fav/resource/deal
原始表单数据rid=113173461999500&type=2&add_media_ids=773769484&del_media_ids=&platform=web&eab_x=2&ramval=440&ga=1&gaia_source=web_normal&csrf=46378a87cb7283a133e9c32b9c09bee7
2.3投币
GET 请求 https://api.bilibili.com/x/v3/fav/folder/created/list-all?type=2&rid=113173461999500&up_mid=484733984
实现代码
import requests
#这是点赞的代码,其他两个改一下url和表单数据即可
def post_bilibili_like(cookie, aid, csrf_token):
url = 'https://api.bilibili.com/x/web-interface/archive/like'
# 表单数据
data = {
'aid': aid,
'like': 1,
'eab_x': 1,
'ramval': 7,
'source': 'web_normal',
'ga': 1,
'csrf': csrf_token
}
headers = {
'Host': 'api.bilibili.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0',
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'Referer': f'https://www.bilibili.com/video/BV{aid}',
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'https://www.bilibili.com',
'Connection': 'keep-alive',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-site',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'Cookie': cookie #cookie
}
# 发送POST请求
response = requests.post(url, headers=headers, data=data)
# 返回请求结果
if response.status_code == 200:
return response.json() # 返回JSON格式的数据
else:
return '点赞失败'
三、直播预约抽奖
通过搜索包搜索获取B站所有的动态抽奖文章,然后GET请求这些文章,得到reserve_id、dynamic_id_str、reserve_total即可成功实现批量直播预约抽奖
详细分析请看以下文章
B站直播预约抽奖协议
直播预约包
POST 请求 https://api.bilibili.com/x/dynamic/feed/reserve/click?csrf=46378a87cb7283a133e9c32b9c09bee7
原始表单数据 {"reserve_id":4073369,"cur_btn_status":1,"dynamic_id_str":"976127207527153680","reserve_total":25439,"spmid":""}
四、动态抽奖|关注|动态转发实现
通过搜索包搜索B站的动态抽奖链接、通过关注包以及转发包即可实现自动动态抽奖
具体分析请看以下文章
B站动态抽奖关注转发协议实现
4.1关注包
POST请求 https://api.bilibili.com//x/relation/modify
请求表单数据act=1&csrf=46378a87cb7283a133e9c32b9c09bee7&extend_content=%7B%22entity%22:%22dt%22,%22entity_id%22:%22977045888118554640%22,%22show_detail%22:1%7D&fid=1575718735&gaia_source=native_h5_main&platform=1&spmid=333.1330.join-btn.0
4.2转发包
POST请求 https://api.bilibili.com//x/dynamic/feed/create/dyn?csrf=46378a87cb7283a133e9c32b9c09bee7&platform=web&x-bili-device-req-json={"platform":"web","device":"pc"}&x-bili-web-req-json={"spm_id":"333.1330"}
请求表单数据:{"dyn_req":{"content":{"contents":[]},"scene":4,"attach_card":null},"web_repost_src":{"dyn_id_str":"977045888118554640"}
实现代码
#转发
def post_url(uid, url, data=None, headers=None, cookie_string=None):
try:
if cookie_string:
headers['Cookie'] = cookie_string
session = requests.Session()
response = session.post(url, data=data, headers=headers)
print(f'状态码: {response.status_code}')
if response.status_code == 200:
try:
if 'gzip' in response.headers.get('Content-Encoding', ''):
response_data = gzip.decompress(response.content).decode('utf-8')
else:
response_data = response.text
print("参与成功")
try:
json_data = json.loads(response_data)
print("响应数据:", json_data)
except json.JSONDecodeError:
pass
except Exception as e:
print("处理响应数据时出错:", e)
else:
print(f'请求失败,状态码:{response.status_code}')
print("响应内容:", response.text)
except Exception as e:
print("请求过程中发生错误:", e)
data = {
"dyn_req": {
"content": {
"contents": []
},
"scene": 4,
"attach_card": None
},
"web_repost_src": {
"dyn_id_str": article_id
}
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0',
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'Content-Type': 'application/json',
'Referer': 'https://www.bilibili.com/',
'Origin': 'https://www.bilibili.com',
'Connection': 'keep-alive',
}
post_url(uid,
f'https://api.bilibili.com/x/dynamic/feed/create/dyn?csrf={bili_jct}&platform=web&x-bili-device-req-json=%7B%22platform%22:%22web%22,%22device%22:%22pc%22%7D&x-bili-web-req-json=%7B%22spm_id%22:%22333.1330%22%7D',
json.dumps(data), headers, cookie_string)
#关注
def post_url(uid, url, data=None, headers=None, cookie_string=None):
try:
if cookie_string:
headers['Cookie'] = cookie_string
session = requests.Session()
response = session.post(url, data=data, headers=headers)
print(f'状态码: {response.status_code}')
if response.status_code == 200:
try:
if 'gzip' in response.headers.get('Content-Encoding', ''):
response_data = gzip.decompress(response.content).decode('utf-8')
else:
response_data = response.text
print("参与成功")
try:
json_data = json.loads(response_data)
print("响应数据:", json_data)
except json.JSONDecodeError:
pass
except Exception as e:
print("处理响应数据时出错:", e)
else:
print(f'请求失败,状态码:{response.status_code}')
print("响应内容:", response.text)
except Exception as e:
print("请求过程中发生错误:", e)
uid = result['uid']
data = {
'fid': uid,
'act': '1',
're_src': '0',
'csrf': bili_jct,
'spmid': '333.1368',
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0',
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'Content-Type': 'application/x-www-form-urlencoded',
'Referer': 'https://www.bilibili.com/read/cv34766197/',
'Origin': 'https://www.bilibili.com',
'Connection': 'keep-alive',
}
post_url(uid, 'https://api.bilibili.com/x/relation/modify', data, headers, cookie_string)