b站动态抽奖全自动脚本实现——b站扫码登录
本篇为b站自动动态抽奖实现第一章,本专栏会尽快更新其他内容
b站扫码登录很简单,不需要逆向分析加密算法,只需几步即可实现
目录
一、抓包分析
小技巧:在b站网页登录界面会有特别多的包,很乱,可以等待二维码失效后,清空之前的数据包再刷新二维码
B站扫码登录所有包都是用GET请求
1.1获取二维码
https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-fe-header&go_url=https://www.bilibili.com/
通过直接访问上面的URL,在相应内容中即可得到二维码的URL 以及参数qrcode_key
1.2登录状态包
https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=e4bc73831b372f8fcd2a1e35e67ff981&source=main-fe-header
通过循环GET请求上面的包,利用在二维码包处得到的qrcode_key即可获取二维码的状态
未扫码
已扫码未确认
登录成功
可以看到,登录成功后,响应中会有一个ckMD5的url,只需要get请求一次这个url即可成功登录
注意每一个包的GET请求都更新Cookie
二、Python代码实现
2.1二维码包
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("未能获取二维码信息")
在二维码包一定要注意保存qrcode_key
结果
2.2状态包
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秒获取一次状态
结果
登录成功结果
{'code': 0, 'message': '0', 'ttl': 1, 'data': {'url': 'https://passport.biligame.com/x/passport-login/web/crossDomain?DedeUserID=484733984&DedeUserID__ckMd5=c4bbe8bf2430ee96&Expires=1742392527&SESSDATA=04ec591b,1742392527,5cea6*91CjDZlpVW6euZPhpTI3FnZ8bkD4Ct_1aO45xbB5GAhgQukNEr30UozdMRPGavyuct1vsSVjB4aThuWXFkOFdadHNtWDRDaHNMenhhRGQ4MXBKTUFlQ1dFY3h0NVZnTGRnOXBQUVJ6Wk1JQkJqMV9FdHJ0UUE3R244T0paSXJ2aG80RDc0ZjR1M0dnIIEC&bili_jct=e6431ba538b182924d30d54d77a8143c&gourl=https%3A%2F%2Fspace.bilibili.com&first_domain=.bilibili.com', 'refresh_token': '0ec30913c755a92901593a29b2f40491', 'timestamp': 1726840527448, 'code': 0, 'message': ''}}
登录成功,跳转URL: https://passport.biligame.com/x/passport-login/web/crossDomain?DedeUserID=484733984&DedeUserID__ckMd5=c4bbe8bf2430ee96&Expires=1742392527&SESSDATA=04ec591b,1742392527,5cea6*91CjDZlpVW6euZPhpTI3FnZ8bkD4Ct_1aO45xbB5GAhgQukNEr30UozdMRPGavyuct1vsSVjB4aThuWXFkOFdadHNtWDRDaHNMenhhRGQ4MXBKTUFlQ1dFY3h0NVZnTGRnOXBQUVJ6Wk1JQkJqMV9FdHJ0UUE3R244T0paSXJ2aG80RDc0ZjR1M0dnIIEC&bili_jct=e6431ba538b182924d30d54d77a8143c&gourl=https%3A%2F%2Fspace.bilibili.com&first_domain=.bilibili.com
2.3ckmd5包
def get_url(url, params=None, headers=None):
if headers is None:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'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',
'Referer': 'https://www.bilibili.com/read/cv34766197/',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1',
'Priority': 'u=1',
'TE': 'trailers'
}
session = requests.Session()
response = session.get(url, params=params, headers=headers)
print(f'GET请求状态码: {response.status_code}')
if response.status_code == 200:
if response.headers.get('Content-Encoding') == 'gzip':
buffer = BytesIO(response.content)
with gzip.GzipFile(fileobj=buffer) as f:
response_text = f.read().decode('utf-8')
elif response.headers.get('Content-Encoding') == 'deflate':
response_text = requests.utils.decode_deflate(response.content)
else:
response_text = response.text
try:
json_data = response.json()
print("JSON解析成功")
return json_data, session.cookies.get_dict()
except ValueError:
print("无法解析JSON响应内容,返回原始文本")
return response_text, session.cookies.get_dict()
else:
print(f'请求失败,状态码:{response.status_code}')
return None, None
注:ckmd5包是没有响应内容的,但是有响应Cookie,这个Cookie就是最终成功登录的Cookie