Python扫码登录保存和验证cookies值——B站篇(六)

python实现扫码登录哔哩哔哩网页版

  • 一、找到相关链接
  • 二、确认链接网址,登录测试
  • 三、验证cookie值是否有效
  • 四、保存cookies值并进行验证完整代码
      • 完整代码
  • 五 、 更多文章

一、找到相关链接

  • 本篇的难度是找到生成二维码图片的网址,和前几篇不一样的是这个登录二维码生成没有网址,只是单纯的base64编码
  • 开始寻找参数

生成需要参数的网址:https://passport.bilibili.com/qrcode/getLoginUrl
生成两个重要参数:urloauthKey

session = requests.session()
getlogin = session.get('https://passport.bilibili.com/qrcode/getLoginUrl', headers=headers).json()
oauthKey = getlogin['data']['oauthKey']
#输出getlogin = {'code': 0, 'status': True, 'ts': 16……, 'data': {'url': 'https://passpor^', 'oauthKey': 'c4a003^'}}
  • 既然找不到相关二维码图片的网址,小编开始在login.796010b9847c1d1cc4ee.js找到下面这段代码
getQrcode: function() {
     
                    var e = this;
                    $.ajax({
     
                        url: "https://passport.bilibili.com/qrcode/getLoginUrl",
                        dataType: "json"
                    }).done(function(t) {
     
                        if (t.status) {
     
                            e.refer ? (e.refer.clear(),
                            e.refer.makeCode(t.data.url)) : e.$nextTick(function() {
     
                                e.refer = new QRCode(e.$refs.qrcode,{
     
                                    text: t.data.url,
                                    width: 140,
                                    height: 140
                                })
                            }),
                            e.key = t.data.oauthKey;
                            var i = decodeURIComponent(Object(f.h)("gourl"));
                            clearTimeout(e.cd),
                            e.cd = setTimeout(e.expire, e.cdTime),
                            clearInterval(e.loop),
                            e.loop = setInterval(function() {
     
                                $.ajax({
     
                                    url: "https://passport.bilibili.com/qrcode/getLoginInfo",
                                    dataType: "json",
                                    type: "POST",
                                    data: {
     
                                        oauthKey: e.key,
                                        gourl: i || (document.referrer || "")
                                    }
                                }).done(function(t) {
     
                                    t.status ? (reportMsgObj.qrcodescan_login = "success",
                                    window.reportObserver && window.reportObserver.forceCommit && window.reportObserver.forceCommit(),
                                    window.location.href = t.data.url) : t.status || -2 != t.message ? t.status || -5 != t.data || e.scanSucess() : e.expire()
                                })
                            }, e.loopTime)
                        }
                    })
                },
  • 通过观察代码,这个二维码Base64是直接由js生成发送前端的
  • e.refer.makeCode(t.data.url))从这段中转换成python
getlogin = session.get('https://passport.bilibili.com/qrcode/getLoginUrl', headers=headers).json()
loginurl = requests.get(getlogin['data']['url'], headers=headers).url
#输出loginurl = https://passport.bilibili.com/mobile/h5-confirm……
  • 输出的loginurl就是二维码隐藏的文字信息,既然要扫码就需要把它生成二维码图片,利用python的import qrcode对这段网址文字信息生成二维码图片,进行扫码操作
class showpng(Thread):
    def __init__(self, data):
        Thread.__init__(self)
        self.data = data

    def run(self):
        img = Image.open(BytesIO(self.data))
        img.show()

loginurl = requests.get(getlogin['data']['url'], headers=headers).url
#生成二维码并进行缓存,
qr = qrcode.QRCode()
qr.add_data(loginurl)
img = qr.make_image()
#缓存的好处就是不需要保存本地
a = BytesIO()
img.save(a, 'png')
png = a.getvalue()
a.close()
#打开二维码进行扫码操作
t = showpng(png)
t.start()

二、确认链接网址,登录测试

  • 上面我们已经搞定了二维码和一个重要参数oauthKey,接下我们找确认链接网址
tokenurl = 'https://passport.bilibili.com/qrcode/getLoginInfo'
#将oauthKey参数带入其中进行访问,获得登录状态信息
qrcodedata = session.post(tokenurl, data={
     'oauthKey': oauthKey, 'gourl': 'https://www.bilibili.com/'}, headers=headerss).json()
#输出 qrcodedata = {'status': False, 'data': -4, 'message': "Can't scan~"}
  • 测试观察发现

‘data’: -4:二维码未失效
‘data’: -5:已扫码
‘data’: -2:二维码已失效
‘status’: True:已登录

  • 判断登录状态,登录成功后生成链接并访问获取真正的cookie值

while 1:
    qrcodedata = session.post(tokenurl, data={
     'oauthKey':oauthKey,'gourl':'https://www.bilibili.com/'}, headers=headerss).json()
    if '-4' in str(qrcodedata['data']):  #'-4' in qrcodedata['data']:
        print('二维码未失效,请扫码!')
    elif '-5' in str(qrcodedata['data']):
        print('已扫码,请确认!')
    elif '-2' in str(qrcodedata['data']):
        print('二维码已失效,请重新运行!')
    elif 'True' in str(qrcodedata['status']):
        print('已确认,登入成功!')
        #最后一步生成的url参数,进行访问获取最终真正的cookie值
        session.get(qrcodedata['data']['url'], headers=headers)
        #登录后停止运行break
        break
    else:
        print('其他:',qrcodedata)
    time.sleep(2)

三、验证cookie值是否有效

  • 通过对比没登陆和登录以后的生成的参数进行对比,就可以判断cookie值
  • 小编找到一个链接可以判断
loginurl = session.get("https://api.bilibili.com/x/web-interface/nav", verify=False, headers=headers).json()
  • 对比比较

没登陆生成的参数:
{‘code’: -101, ‘message’: ‘账号未登录’, ‘ttl’: 1, ‘data’: {‘isLogin’: False}}
登录后生成的参数:
{‘code’: 0, ‘message’: ‘0’, ‘ttl’: 1, ‘data’: {‘isLogin’: Tr……}

  • 下面判断代码
loginurl = session.get("https://api.bilibili.com/x/web-interface/nav", verify=False, headers=headers).json()
if loginurl['code'] == 0:
    print('Cookies值有效,',loginurl['data']['uname'],',已登录!')
    return session, True
else:
    print('Cookies值已经失效,请重新扫码登录!')
    return session, False

四、保存cookies值并进行验证完整代码

完整代码

# -*- coding: utf-8 -*-
import qrcode
import agent
from threading import Thread
import time
import requests
from io import BytesIO
import http.cookiejar as cookielib
from PIL import Image
import os

requests.packages.urllib3.disable_warnings()

headers = {
     'User-Agent': agent.get_user_agents(), 'Referer': "https://www.bilibili.com/"}
headerss = {
     'User-Agent': agent.get_user_agents(),  'Host': 'passport.bilibili.com','Referer': "https://passport.bilibili.com/login"}

class showpng(Thread):
    def __init__(self, data):
        Thread.__init__(self)
        self.data = data

    def run(self):
        img = Image.open(BytesIO(self.data))
        img.show()


def islogin(session):
    try:
        session.cookies.load(ignore_discard=True)
    except Exception:
        pass
    loginurl = session.get("https://api.bilibili.com/x/web-interface/nav", verify=False, headers=headers).json()
    if loginurl['code'] == 0:
        print('Cookies值有效,',loginurl['data']['uname'],',已登录!')
        return session, True
    else:
        print('Cookies值已经失效,请重新扫码登录!')
        return session, False


def bzlogin():
    if not os.path.exists('bzcookies.txt'):
        with open("bzcookies.txt", 'w') as f:
            f.write("")
    session = requests.session()
    session.cookies = cookielib.LWPCookieJar(filename='bzcookies.txt')
    session, status = islogin(session)
    if not status:
        getlogin = session.get('https://passport.bilibili.com/qrcode/getLoginUrl', headers=headers).json()
        loginurl = requests.get(getlogin['data']['url'], headers=headers).url
        oauthKey = getlogin['data']['oauthKey']
        qr = qrcode.QRCode()
        qr.add_data(loginurl)
        img = qr.make_image()
        a = BytesIO()
        img.save(a, 'png')
        png = a.getvalue()
        a.close()
        t = showpng(png)
        t.start()
        tokenurl = 'https://passport.bilibili.com/qrcode/getLoginInfo'
        while 1:
            qrcodedata = session.post(tokenurl, data={
     'oauthKey': oauthKey, 'gourl': 'https://www.bilibili.com/'}, headers=headerss).json()
            print(qrcodedata)
            if '-4' in str(qrcodedata['data']):
                print('二维码未失效,请扫码!')
            elif '-5' in str(qrcodedata['data']):
                print('已扫码,请确认!')
            elif '-2' in str(qrcodedata['data']):
                print('二维码已失效,请重新运行!')
            elif 'True' in str(qrcodedata['status']):
                print('已确认,登入成功!')
                session.get(qrcodedata['data']['url'], headers=headers)
                break
            else:
                print('其他:', qrcodedata)
            time.sleep(2)
        session.cookies.save()
    return session

if __name__ == '__main__':
    bzlogin()

五 、 更多文章

  1. 抖音篇(一)
  2. 快手篇(二)
  3. 微视篇(三)
  4. 微信公众号篇(四)
  5. 微博篇(五))
  6. 视频号篇(七)
  • 后期小编将开设登录后批量采集各平台数据(点赞、播放量、评论、图片、视频、音乐等)专栏文章!记得关注哟!
  • 如果文章能帮到您,愿意给小编点个 吗,么么哒~ (●’◡’●)

你可能感兴趣的:(Python实现扫码登录,python,session,cookie,js)