吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2138|回复: 15
收起左侧

[Python 原创] python扫码获取B站cookie文件

  [复制链接]
zboi 发表于 2024-3-22 14:57
该脚本主要是根据这篇文章Python扫码登录保存和验证cookies值——B站篇(六)修改过来的,增加了一个tk界面,以及注销登录的功能。
首次运行之后,会显示一个二维码,客户端扫码之后点击确认即可登录,登录成功之后,会显示账号的头像。点击注销登录之后,会将当前的登录状态注销,同时又刷新一个登录二维码。
扫码成功后,再运行脚本,则会优先读取已保存的cookie文件,如果cookie信息有效,则会直接显示B站头像,如果失效,则会显示二维码。
具体效果如下:
image.png           微信图片_20240322145202.png
代码如下:
[Python] 纯文本查看 复制代码
from time import sleep
from http.cookiejar import LWPCookieJar
import requests
from re import findall
from tkinter import StringVar, Tk, messagebox
from os import path
from io import BytesIO
from PIL import Image, ImageTk
from qrcode import QRCode
from tkinter.ttk import Button, Label
from threading import Thread


temp_cookie_file = 'bz-cookie.txt'
headers = {
    'authority': 'api.vc.bilibili.com', 'accept': 'application/json, text/plain, */*',
    'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', 'content-type': 'application/x-www-form-urlencoded',
    'origin': 'https://message.bilibili.com', 'referer': 'https://message.bilibili.com/',
    'sec-ch-ua': '"Chromium";v="116", "Not)A;Brand";v="24", "Microsoft Edge";v="116"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-site',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81',
}


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


def scan_code(session2):
    global bili_jct, tk_image
    get_login = session2.get('https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-fe-header', headers = headers).json()
    qrcode_key = get_login['data']['qrcode_key']
    qr = QRCode()
    qr.add_data(get_login['data']['url'])
    img = qr.make_image()
    pil_image_change = img.resize((200, 200), resample = Image.BICUBIC, box = None, reducing_gap = None)
    tk_image = ImageTk.PhotoImage(pil_image_change)
    token_url = f'https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={qrcode_key}&source=main-fe-header'
    v1.set('等待扫码')
    label_code.config(image = tk_image)
    while 1:
        qrcode_data = session2.get(token_url, headers = headers).json()
        if qrcode_data['data']['code'] == 0:
            v1.set('扫码成功')
            session2.get(qrcode_data['data']['url'], headers = headers)
            break
        else:
            v1.set(qrcode_data['data']['message'])
        sleep(1)
    session2.cookies.save()
    with open(temp_cookie_file, 'r', encoding = 'utf-8') as f:
        bzcookie = f.read()
    bili_jct = findall(r'bili_jct=(.*?);', bzcookie)[0]


def bz_login():
    login_session.cookies = LWPCookieJar(filename = temp_cookie_file)
    status = is_login(login_session)
    if not status:
        scan_code(login_session)
    verification()


def verification():
    url = 'https://api.bilibili.com/x/web-interface/nav'
    resp1 = login_session.get(url = url, headers = headers).json()
    global tk_image
    if resp1['data']['isLogin']:
        face_url = resp1['data']['face']
        image_bytes = requests.get(face_url).content
        data_stream = BytesIO(image_bytes)
        pil_image = Image.open(data_stream)
        pil_image_change = pil_image.resize((200, 200), resample = Image.BICUBIC, box = None, reducing_gap = None)
        tk_image = ImageTk.PhotoImage(pil_image_change)
        status = "cookie有效!登录成功!"
        v1.set(status)
    else:
        thread_it(bz_login)
    label_code.config(image = tk_image)



def thread_it(func, *args):
    thread = Thread(target = func, args = args, daemon = True)
    thread.start()


def cancel_login():
    msg1 = messagebox.askyesno(title = "提示", message = "注销后cookie将失效,是否注销登录?")
    if msg1:
        url3 = 'https://passport.bilibili.com/login/exit/v2'
        data3 = {'biliCSRF': f'{bili_jct}'}
        login_session.post(url = url3, headers = headers, data = data3).json()
        verification()




if __name__ == '__main__':
    root = Tk()
    v1 = StringVar()
    if not path.exists(temp_cookie_file):
        with open(temp_cookie_file, 'w', encoding = 'utf-8') as f:
            f.write("")
    with open(temp_cookie_file, 'r', encoding = 'utf-8') as f:
        bzcookie = f.read()
    try:
        bili_jct = findall(r'bili_jct=(.*?);', bzcookie)[0]
    except Exception as e:
        print(e)
    requests.packages.urllib3.disable_warnings()
    login_session = requests.session()
    root.geometry('300x225')
    root.title("B站cookie获取")
    thread_it(bz_login)
    btn1 = Button(root, width=10, text='注销登录', command=cancel_login)
    btn1.grid(row=3, column=2)
    label_ver2 = Label(root, textvariable = v1)
    label_ver2.grid(row = 9, column = 1, rowspan = 8, columnspan = 1, sticky = 'n')
    white_image = Image.new('RGB', (200, 200), (256, 256, 256))
    tk_image = ImageTk.PhotoImage(white_image)
    label_code = Label(root, image = tk_image)
    label_code.grid(row = 1, column = 1, rowspan = 8, columnspan = 1, sticky = 'n')
    root.mainloop()

免费评分

参与人数 3吾爱币 +9 热心值 +3 收起 理由
machuhai + 1 + 1 我很赞同!
傲雪不傲霜 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

stiller 发表于 2024-3-31 23:11
stiller 发表于 2024-3-31 17:06
抄了半天,QLabel无论如何没法正常直接显示生成的二维码img,实在诡异;
qr.make_image()返回的是PilImage ...

改了PyQt5的,能跑,但除了QPixmap转换之外,session跟thread也一样糊涂,还是搞不明白

[Python] 纯文本查看 复制代码
import sys
from http.cookiejar import LWPCookieJar
from io import BytesIO
from pathlib import Path
from re import findall
from threading import Thread
from time import sleep

import requests
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QWidget, QApplication, QFrame, QVBoxLayout, QPushButton, QLabel, QHBoxLayout, QMessageBox
from qrcode.main import QRCode


class TestClass(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.resize(300, 225)
        self.setWindowTitle('B站cookie获取')
        # 初始化UI
        self.init_func()
        # 一些常规任务
        self.init_do()

    def init_func(self):
        # mid_f 这层只是为了规避QSS刷新机制BUG
        mid_f = QFrame(self)
        mid_f.setFrameShape(QFrame.Panel)
        # 二维码显示框框
        self.label_code = QLabel(mid_f)
        self.label_code.setFrameShape(QFrame.Panel)
        self.label_code.setFixedSize(200, 200)
        # 一个按钮
        self.btn1 = QPushButton('注销登录', mid_f, clicked=self.cancel_login)
        # 下部状态提示框框 (Main window自带就有状态栏,只是我喜欢用QWidget从头搭建)
        self.label_ver2 = QLabel(mid_f)
        self.label_ver2.setFrameShape(QFrame.Panel)

        # 子控件布局
        v_lo = QHBoxLayout()
        v_lo.addWidget(self.label_code)
        v_lo.addWidget(self.btn1)
        # mid_f的布局 多加一层是刷新机制原因,某种情况下一级布局QSS样式不刷新
        midf_lo = QVBoxLayout(mid_f)
        midf_lo.addLayout(v_lo)
        midf_lo.addWidget(self.label_ver2)
        midf_lo.setStretch(0, 1)
        # self的布局
        self_lo = QVBoxLayout(self)
        self_lo.setContentsMargins(6, 6, 6, 6)
        self_lo.addWidget(mid_f)

    def init_do(self):
        print('init_do')
        self.temp_cookie_file = 'cookie.txt'  # ccokies存放的位置
        self.headers = {
            'authority': 'api.vc.bilibili.com', 'accept': 'application/json, text/plain, */*',
            'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
            'content-type': 'application/x-www-form-urlencoded',
            'origin': 'https://message.bilibili.com', 'referer': 'https://message.bilibili.com/',
            'sec-ch-ua': '"Chromium";v="116", "Not)A;Brand";v="24", "Microsoft Edge";v="116"', 'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"Windows"',
            'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-site',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81',
        }
        self.bili_jct = ""

        # 不存在则新建一个文件
        if not Path(self.temp_cookie_file).exists():
            with open(self.temp_cookie_file, 'w', encoding='utf-8') as f:
                f.write("")
            print('文件不存在,已新建')

        with open(self.temp_cookie_file, 'r', encoding='utf-8') as f:
            bzcookie = f.read()

        try:
            self.bili_jct = findall(r'bili_jct=(.*?);', bzcookie)[0]
        except Exception as e:
            print(e)

        requests.packages.urllib3.disable_warnings()
        self.login_session = requests.session()
        self.thread_it(self.bz_login)
        print('init_do out')

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

    def scan_code(self, session2):
        url = 'https://passport.bilibili.com/x/passport-login/web/qrcode/generate?source=main-fe-header'
        get_login = session2.get(url, headers=self.headers).json()
        print(f'get_login:{get_login}')
        qrcode_key = get_login['data']['qrcode_key']
        qr = QRCode()
        qr.add_data(get_login['data']['url'])
        img = qr.make_image()
        img = img.resize((200, 200))  # resize不会改变原对象,而是返回一个新对象。
        img.save('qrcimg.png')
        self.label_code.setPixmap(QPixmap('qrcimg.png'))
        token_url = f'https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={qrcode_key}&source=main-fe-header'
        self.label_ver2.setText('等待扫码')

        while 1:
            print('进入while')
            qrcode_data = session2.get(token_url, headers=self.headers).json()
            print(f'qrcode_data:{qrcode_data}')
            if qrcode_data['data']['code'] == 0:
                self.label_ver2.setText('扫码成功')
                print('扫码成功')
                session2.get(qrcode_data['data']['url'], headers=self.headers)
                break
            else:
                print('扫码失败')
                self.label_ver2.setText(qrcode_data['data']['message'])
            sleep(1)

        session2.cookies.save()

        with open(self.temp_cookie_file, 'r', encoding='utf-8') as f:
            bzcookie = f.read()
            print(f'bzcookie:{bzcookie}')

        self.bili_jct = findall(r'bili_jct=(.*?);', bzcookie)[0]
        print(f'bili_jct:{self.bili_jct}')

    def bz_login(self):
        print('bz_login')
        self.login_session.cookies = LWPCookieJar(filename=self.temp_cookie_file)
        print(f'self.login_session.cookies:{self.login_session.cookies}')
        status = self.is_login(self.login_session)
        if not status:
            print(status, '没有登陆')
            self.scan_code(self.login_session)

        self.verification()

    def verification(self):
        print('verification')
        url = 'https://api.bilibili.com/x/web-interface/nav'
        resp1 = self.login_session.get(url=url, headers=self.headers).json()
        print(resp1)
        if resp1['data']['isLogin']:
            face_url = resp1['data']['face']
            image_bytes = requests.get(face_url).content
            imgxx = QPixmap()
            imgxx.loadFromData(BytesIO(image_bytes).getvalue())
            imgxx = imgxx.scaled(200, 200)
            self.label_code.setPixmap(imgxx)
            status = "cookie有效!登录成功!"
            self.label_ver2.setText(status)
        else:
            self.thread_it(self.bz_login)

    def cancel_login(self):
        print('cancel_login')
        msgbox = QMessageBox.information(self, "提示", "注销后cookie将失效,是否注销登录?",
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if msgbox == QMessageBox.Yes:
            print('要注销')
            url3 = 'https://passport.bilibili.com/login/exit/v2'
            data3 = {'biliCSRF': f'{self.bili_jct}'}
            try:
                self.login_session.post(url=url3, headers=self.headers, data=data3).json()
            except:
                return
            self.verification()
            return

    def thread_it(self, func, *args):
        thread = Thread(target=func, args=args, daemon=True)
        thread.start()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    Test_Class = TestClass()
    Test_Class.show()
    sys.exit(app.exec_())
stiller 发表于 2024-3-31 17:06
抄了半天,QLabel无论如何没法正常直接显示生成的二维码img,实在诡异;
qr.make_image()返回的是PilImage对象;
PilImage对象要转换为Image对象,再转换为QPixmap对象;
按道理应该是:
qrc_lb.setPixmap(QPixmap(QImage(qr.make_image())))
但是没用

[Python] 纯文本查看 复制代码
import sys
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QWidget, QApplication, QFrame, QVBoxLayout, QGridLayout, QLabel
from qrcode.main import QRCode


class TestClass(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.resize(500, 309)
        self.init_func()

    def init_func(self):
        self_lo = QVBoxLayout(self)
        mid_f = QFrame(self)
        mid_f.setFrameShape(QFrame.Panel)
        self_lo.addWidget(mid_f)
        self_lo.setContentsMargins(6, 6, 6, 6)
        midf_lo = QGridLayout(mid_f)
        qrc_lb = QLabel(mid_f)
        midf_lo.addWidget(qrc_lb)

        qrcode_key = '6d483c43912989323623120e0b77464f'
        qr = QRCode()
        qr.add_data(qrcode_key)
        img = qr.make_image()
        img.save('test.jpg', 'JPEG')
        qrc_lb.setPixmap(QPixmap('test.jpg'))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    Test_Class = TestClass()
    Test_Class.show()
    sys.exit(app.exec_())

anchovy126 发表于 2024-3-22 16:43
头像被屏蔽
52down 发表于 2024-3-22 17:12
提示: 作者被禁止或删除 内容自动屏蔽
gdp123gd 发表于 2024-3-22 17:28
感谢,正好要用
cwpycyy 发表于 2024-3-22 19:14
感谢,试试看自已能用不
lvtaode0657 发表于 2024-3-22 20:01
不错哦,学习了。感谢分享
撒旦の恶 发表于 2024-3-23 15:28
那篇文章之前有看过,没记错的话那篇文章中好像有调用一个js文件的。大佬你这代码中貌似不用,能粗略解答下为什么吗?蟹蟹啦
 楼主| zboi 发表于 2024-3-23 16:16
撒旦の恶 发表于 2024-3-23 15:28
那篇文章之前有看过,没记错的话那篇文章中好像有调用一个js文件的。大佬你这代码中貌似不用,能粗略解答下 ...

其实他的那篇文章也没用调用js,只不过是通过python实现js的作用,你可以在仔细看看原文,原文给出的python代码并没有调用js
撒旦の恶 发表于 2024-3-24 09:42
zboi 发表于 2024-3-23 16:16
其实他的那篇文章也没用调用js,只不过是通过python实现js的作用,你可以在仔细看看原文,原文给出的pyth ...

原文章中的agent模块,之前看时里面有涉及js文件读取就以为有调用。
tianya0908 发表于 2024-3-25 12:05
不错哦,学习了。感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-12 07:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表