在Python中用Request库模拟登录:哔哩哔哩(有加密,有验证码)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Python中用Request库模拟登录:哔哩哔哩(有加密,有验证码)相关的知识,希望对你有一定的参考价值。

 

抓包分析

获取验证码

技术分享

获取加密公钥

技术分享

其中hash是变化的,公钥key不变

登录

技术分享

其中用户名没有被加密,密码被加密。

因为在获取公钥的时候同时返回了一个hash值,推测此hash值与密码加密有关。

通过谷歌浏览器控制台分析js代码

 右键登录按钮,检查,查看 Event Listeners ,点击a.btn.btn-login右边的login.4f030c3....js:6查看js代码。

技术分享

点击左下角的{}展开代码

技术分享

因为获取公钥和hash的链接中有action=getkey,尝试在源代码中搜索getkey,于是找到这样一个函数:

 1 encryptPassword: function (e, t) {
 2     var n = this,
 3     r = !1;
 4     return $.ajax({
 5         url: "https://passport.bilibili.com/login?act=getkey&r=" + Math.random(),
 6         async: !1
 7     }).done(function (t) {
 8         t && t.error && (n.publicTip = "登录失败,服务端出现异常", e = null);
 9         var i = new JSEncrypt;
10         i.setPublicKey(t.key);
11         var a = i.encrypt(t.hash + e);
12         e = a,
13         r = !0
14     }),
15     r ? e : ""
16 }

 观察第10、11行,可知hash和变量e相加后被RSA加密,现在需要确定e是什么。在第11行代码所在的位置设置一个断点,输入用户名密码验证码之后点击登录,在这里密码框输入的是‘mypassword’

技术分享

点击e就会显示出e的值,看来e就是密码明文。

于是,可以猜测,加密的过程是:密码字符串前面串接hash值,然后进行RSA加密。下面通过测试检查猜测是否正确。

模拟登录

每一次请求的headers都完全复制抓包的内容。

1.获取验证码

1 def get_code():
2     url=https://passport.bilibili.com/captcha?r=0.1265352187487443
3     headers={复制抓包到的headers}
4     session.headers.clear()
5     session.headers.update(headers)
6     r=session.get(url)
7     file=open(code.jpg,wb)
8     file.write(r.content)
9     file.close()

2.getkey

1 def get_key():
2     url=https://passport.bilibili.com/login?act=getkey&r=0.4365052982637341
3     headers={复制抓包到的headers}
4     session.headers.clear()
5     session.headers.update(headers)
6     r=session.get(url)
7     jsondata=json.loads(r.text)
8     #hash变化,key不变
9     return (jsondata[hash],jsondata[key])

3.加密,具体可以参考博客园的模拟登录的附录部分

1 def encrypt(Hash,key,password):
2     from Crypto.PublicKey import RSA
3     from Crypto.Cipher import PKCS1_v1_5
4     from base64 import b64encode
5     encryptor=PKCS1_v1_5.new(RSA.importKey(bytes(key,utf-8)))
6     return str(b64encode(encryptor.encrypt(bytes(Hash+password,utf-8))),utf-8)

4.登录

 1 def login(code,username,password):
 2     #注意,在登录页面中验证码会自动转成大写
 3     url=https://passport.bilibili.com/web/login
 4     headers={复制抓包到的headers}
 5     data={cType:2,
 6           vcType:1,
 7           captcha:code,
 8           user:username,
 9           pwd:password,
10           keep:true,
11           gourl:http://www.bilibili.com/}
12     session.headers.clear()
13     session.headers.update(headers)
14     r=session.post(url,data=data)
15     return r.text

如果登录成功,将返回 "code":0

5.测试

testurl=https://www.bilibili.com/account/dynamic

在未登录时,testurl的标题为“bilibili - 提示”,登录时标题为“哔哩哔哩 (゜-゜)つロ 干杯~-bilibili”

session.headers.clear()
r=session.get(testurl)
p=r.text.find(<title>)+len(<title>)
print(r.text[p:r.text.find(<,p)])

以上是关于在Python中用Request库模拟登录:哔哩哔哩(有加密,有验证码)的主要内容,如果未能解决你的问题,请参考以下文章

在Python中用Request库模拟登录:博客园(简单加密,无验证码)

《哔哩哔哩》查看自己发布的全部评论记录方法

哔哩哔哩电脑怎么设置弹幕?

python 哔哩哔哩学习

哔哩哔哩怎么看到自己的评论

爬取哔哩哔哩全站所有投稿在 2020年03月09日 - 2020年03月12日 的播放前百视频