二、扫码登陆bilibili

时间:2024-01-21 19:59:37

考虑到B站移动滑块登陆比较难而且成功率一般
故而采用了简单的二维码登陆
至少常用的PC+手机的网站都支持二维码登录
滑块登陆链接:https://blog.csdn.net/One_of_them/article/details/82820981
一、登陆流程
1、判断用户是否已经登录了
Get https://account.bilibili.com/home/userInfo
2、获取二维码地址
Get https://passport.bilibili.com/qrcode/getLoginUrl
3、根据地址生成二维码

pip install qrcode
pip install matplotlib

4、 循环判断是否扫码
Post https://passport.bilibili.com/qrcode/getLoginInfo!

data={
        'oauthKey':oauthKey,
        'gourl': 'https://passport.bilibili.com/account/security'
 }

4、获取个人信息
Get https://api.live.bilibili.com/User/getUserInfo

代码实现

二、API层 api.py

  1. API应满足单例模式
  2. ajax 负责管理所有请求
  3. 添加Login类负责登录
  4. 添加统一接口类BilibiliAPI
from utils import singleton
def ajax(s,url,method='GET',data=None):
    if method=='GET':return http.get(s,url,data)
    else:return http.post(s,url,data)

class Login():
    def isLogin(self,s):
        url="https://account.bilibili.com/home/userInfo"
        return ajax(s,url)

    def get_vdcode(self,s):
        url="https://passport.bilibili.com/qrcode/getLoginUrl"
        return ajax(s,url)

    def loop_vdcode(self,s,oauthKey):
        url="https://passport.bilibili.com/qrcode/getLoginInfo"
        data={
                'oauthKey':oauthKey,
                'gourl': 'https://passport.bilibili.com/account/security'
            }
        return ajax(s,url,'POST',data)
@singleton
class BilibiliAPI():pass
BilibiliAPI.Login=Login()

三、服务层 server.py

from api import BilibiliAPI as API
class Login():
    def __init__(self,s):
        self.s=s
        self.oauthKey=''
        self.s._type='json'
    def isLogin(self):
        r=API.Login.isLogin(self.s)
        if r['code']==-101:return False
        else:return self.get_info()
    def get_info(self):
        r=API.User.get_info(s)
        self.info=r['data']
        return True
    def get_vdcode(self):
        r=API.Login.get_vdcode(self.s)
        code_url=r['data']['url']
        img=self.make_vdcode(code_url)
        self.show_img(img)
        self.oauthKey=r['data']['oauthKey']
    def show_img(self,img):
        import matplotlib.pyplot as plt
        plt.imshow(img)  
        plt.show()
    def make_vdcode(self,code_url):
        import qrcode
        return qrcode.make(code_url)
    def loop_vdcode(self):
        import time
        r=API.Login.loop_vdcode(self.s,self.oauthKey)
        while not r['status']:
            time.sleep(1)
            r=API.Login.loop_vdcode(self.s,self.oauthKey)
            if r['data']==-2:
                print('二维码已过期')
                break
        if r['status']:self.info=r['data']
        return r['status']

四、测试代码

headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.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',
    'Referer': 'https://live.bilibili.com/',
    'Origin': 'https://live.bilibili.com',
    'Connection': 'keep-alive'
    }
s=session(headers,'cookie.txt')
login=Login(s)
while not login.isLogin():
    login.get_vdcode()
    login.loop_vdcode()
s.save()

cookie.txt

#LWP-Cookies-2.0
Set-Cookie3: DedeUserID=269938304; path="/"; domain=".bilibili.com"; path_spec; domain_dot; expires="2018-10-29 12:11:55Z"; version=0
Set-Cookie3: DedeUserID__ckMd5=e3b81ec041161182; path="/"; domain=".bilibili.com"; path_spec; domain_dot; expires="2018-10-29 12:11:55Z"; version=0
Set-Cookie3: SESSDATA="136e3f28%2C1540815115%2C4df7c156"; path="/"; domain=".bilibili.com"; path_spec; domain_dot; expires="2018-10-29 12:11:55Z"; HttpOnly=None; version=0
Set-Cookie3: bili_jct=957f743c8c8ad984fc6d260f43963242; path="/"; domain=".bilibili.com"; path_spec; domain_dot; expires="2018-10-29 12:11:55Z"; version=0
Set-Cookie3: sid=c5g6gj6d; path="/"; domain=".bilibili.com"; path_spec; domain_dot; expires="2019-09-29 12:12:11Z"; version=0