前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【教程】最新可用! Python实现QQ扫码登录的群验证

【教程】最新可用! Python实现QQ扫码登录的群验证

原创
作者头像
小锋学长生活大爆炸
发布2024-04-26 04:38:34
890
发布2024-04-26 04:38:34
举报
文章被收录于专栏:学习之旅学习之旅

转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn]

目录

背景说明

使用效果

参考代码

扫码登录(备份)


背景说明

Q群验证就是为了验证某个用户是否加入了指定的群聊。这可以有很多作用,比如限制软件的使用人群,以防滥用。

使用效果

参考代码

代码语言:javascript
复制
from PyQt5.QtCore import QUrl, Qt
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QMessageBox, QHBoxLayout, QLabel
import sys
 
class QQGroupLogin(QWidget):
    def __init__(self, groupid="913182235"):
        super().__init__()      # 调用父类的构造函数
        self.init_ui()          # 初始化用户界面
        self.groupid = groupid  # 指定的QQ群ID
        
    def init_ui(self):
        self.setWindowTitle('QQ群验证登录 by 小锋学长生活大爆炸')  # 设置窗口标题
        layout = QVBoxLayout()  # 创建一个垂直布局
        self.loading_label = QLabel('页面加载中,请稍候...')
        layout.addWidget(self.loading_label)  # 添加加载提示到布局
        # 创建并配置Web浏览器组件
        self.browser = QWebEngineView()
        # 加载指定的URL,即QQ登录页面
        self.browser.load(QUrl("https://xui.ptlogin2.qq.com/cgi-bin/xlogin?pt_disable_pwd=1&appid=715030901&daid=73&hide_close_icon=1&pt_no_auth=1&s_url=https%3A%2F%2Fqun.qq.com%2Fmember.html%23"))
        self.browser.setMinimumSize(600, 400)  # 设置浏览器组件的最小大小
        layout.addWidget(self.browser)  # 将浏览器组件添加到布局中
        # 连接页面加载信号
        self.browser.loadStarted.connect(self.on_load_started)
        self.browser.loadFinished.connect(self.on_load_finished)
        # 创建一个水平布局来放置按钮
        button_layout = QHBoxLayout()
        # 创建“刷新页面”按钮,并绑定点击事件到浏览器的reload方法以刷新页面
        self.refresh_button = QPushButton('刷新页面')
        self.refresh_button.setStyleSheet("font-size: 16px; height: 36px;")
        self.refresh_button.clicked.connect(self.browser.reload)
        button_layout.addWidget(self.refresh_button)  # 将按钮添加到按钮布局中
        # 创建“检查验证”按钮,用于触发验证过程
        self.check_button = QPushButton('检查验证')
        self.check_button.setStyleSheet("font-size: 16px; height: 36px;")
        self.check_button.clicked.connect(self.check_verification)
        button_layout.addWidget(self.check_button)  # 将按钮添加到按钮布局中
        layout.addLayout(button_layout)  # 将按钮布局添加到主布局中
        self.setLayout(layout)  # 设置窗口的布局为之前创建的布局
        self.resize(800, 600)  # 设置窗口的初始大小
        self.center_on_screen()  # 将窗口居中显示
        self.show()  # 显示窗口
        
    def center_on_screen(self):
        # 计算并应用窗口居中的位置,确保使用整数进行move调用
        resolution = self.screen().availableGeometry()
        self.move(int((resolution.width() / 2) - (self.frameSize().width() / 2)),
                  int((resolution.height() / 2) - (self.frameSize().height() / 2)))
    
    def on_load_started(self):
        self.loading_label.setVisible(True)  # 显示加载提示
    
    def on_load_finished(self, ok):
        self.loading_label.setVisible(False)  # 隐藏加载提示
        
    def check_verification(self):
        # 请求当前页面的HTML内容,用于后续处理
        self.browser.page().toHtml(self.process_page_source)
        
    def process_page_source(self, html):
        # 处理页面源代码,检查用户是否已加入指定的QQ群
        if "data-id=\"{}\"".format(self.groupid) in html:
            QMessageBox.information(self, '验证结果', '恭喜,验证成功!')
        else:
            QMessageBox.warning(self, '验证结果', '您尚未加入指定的QQ群,请加群后再尝试。')
 
if __name__ == '__main__':
    # 如果不需要调整缩放,可以注释掉下面这行
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)  # 新增加的,针对高DPI屏幕自动缩放
    app = QApplication(sys.argv)  # 创建应用程序实例
    ex = QQGroupLogin()  # 创建窗口实例
    sys.exit(app.exec_())  # 启动应用程序的事件循环

扫码登录(备份)

        这段代码只作为备份,因为扫码登录能用,但Q群验证这个不行了。Q群验证还得是用上面的方法。

代码语言:javascript
复制
import requests
from PIL import Image, ImageTk
import tkinter as tk
import time
import re
import sys
from io import BytesIO  # 用于将二进制内容转换为文件类对象,以便Image.open使用
import base64
 
 
class QQGroupLogin:
    def __init__(self):
        # 初始化会话以跟踪cookies和headers
        self.session = requests.Session()
 
    @staticmethod
    def compute_bkn(skey):
        # 计算bkn,某些请求所需的参数
        t = 5381
        for character in skey:
            t += (t << 5) + ord(character)
        return t & 2147483647
 
    @staticmethod
    def compute_ptqrtoken(qrsig):
        # 根据qrsig计算ptqrtoken,用于二维码验证
        e = 0
        for character in qrsig:
            e += (e << 5) + ord(character)
        return 2147483647 & e
 
    def fetch_qr_code(self):
        # 获取登录的二维码
        print("正在获取登录二维码...")
        url = f'https://ssl.ptlogin2.qq.com/ptqrshow?appid=715030901&e=2&l=M&s=3&d=72&v=4&t={time.time()}&daid=73&pt_3rd_aid=0'
        response = self.session.get(url)
        qrsig = response.cookies.get('qrsig')
        return response.content, qrsig
 
    def display_qr(self, content):
        # 显示登录用的二维码
        print("请扫描二维码登录。")
        root = tk.Tk()
        root.title("QQ扫码登录 by 小锋学长生活大爆炸")  # 设置窗口标题
        icon_base64 = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABQhJREFUWEe9lm1MU1ccxp9zS4HSYkenRgGpG2wCYgVkRLeBmGimcWNsswsMFxD2YfswlzmCMLKED2TTbdmWDLOXDxS7zLoNPigZzBgcW8ROgZkJBUFgo04l6GjB8tKXe89yL7ShtYVbJZ4PNzfnPOf//53nvBJd3w2KByyUUG1JYmzD/YQhPMCk034/fYU+K6RhWBaAq5NjQUPEyJSIiVixPABBZ5/vsCwOBJN8tGcMMxPeU2a9Pvmj9bqlb2EcCuauhHM11tcX/LNYfGENrIkIxUaVIqDu/C0r7CwntBu/7cKsD0CgjgSk/njdvgOiAHbHrQyoM1wb9QD8+skF0YZRirbvdNodogFMJhM6Ojo8+uLiYuF/IcD6GQ4JapVQT0H5D2QSxiyVMBNCJW8UMxfi4DtNKr1OGxsUAA+hVqvR0tKC6upqvwA5aYvG9OQrKmkw63VaddAAa9euRWtra0CAG72/ecUsLCxET08PmpubPfXl5eUoKm34W1+nfTwogN7eXo9eq9X6dcDcfQ4SiURoGxkZQW5urvBfVVWFgoICGAwGnDp1CkUlPw3pda8miAYIJPRdAzyAVCqF1WqFxWLB9PQ08vPz7wUobRzQ1+3bIAogXhkRUNc5Ninsgij6H5SzUeAB+JHzhXeC4zjk5eUJAO4iOFDa2Kev25e8JMBiAnfbBtYEDduFDnY/RvvPCyM+efIkUlJS0N7ejqSkJAwNDSE6OhpNTU2ora1FUUmDSa/TpiwJIOYyepp2IQmDMDoLsXPLOq+YNTU1HgfKysqQlZUltBeXNnQfr9NqRAEsdRlFMza8GXEZRvtL6GtrFEa90O7PPj3iLHl+3SU4rOGK2Cw2RKXJPHb02ER2xp10zc7q4UAQoq9jKZyIxShkjsfwZ6sBcXFxczvEYBBWvmTWfDtv7/ZVIcpEzAyfQOiqp4x1OmPy3q3j/ZGqFXuUGw+N+4MQAMSsgXT2IuLZfnSwr+PS2e/vcaCv43T/E/HqDZRzwXHzrBBywMxOrVS65Cpl6BkipQfkyVW3fHN5HFhqCrZJb+Dl8AGcm9Xihcx4v8wz/d8YObtlm6eRos08astRKcMgl0nbQyj2y9IqvW5HD8BdEa+ircxVuFxpeC4j8OnqBUHRBoKcCZsDSkUof2/8RTn6WmT6+57TTvQUhMGOXMcPwhTkpMUsOmtTps8HwNqfxDyAj1iv2FxZ5K4T7YAULEpDzqDT8cqiDvCB7cMnulw285YAALxkj2Jz5S/8j+g1wIs1IWOIIcmYdbKwO1kwHAOGBajNeYWzsxOy8BDJI1EyV6ry5zVhZOqmMEqCHF+7KMXXkamVb3kAxOwCt8b3QaJarUDZu88O3zRbzbVf/SEkq317aIhhaHwgBwjFBXlq5TNeDoiF6Pqiy0uasHE1PjiUjWuDd36v+agtex7gX4ahsQEBABsYZod80+HOoKaAD+4wWsBZnAJEpIRCSiSIflR+a/y2zTpumXbwS31X+gSzK2OcEoB/Jc2dy34KBf1Q9EnoL0AkppBJrmI9NyjWQF9duehtuFgGNdf/XiZ7MR0UhWJJCHBavrnyRUIp79SDF0IInTYdzaQsfYNSuhuA95W5IAUBLk+HMdtXJR6+uyzJ/eHbTB+nUpcrGxxVgWHyCeB+GY0SQkrkmoqWuV36EMp45xFlaChXAUoqGIYcjNhU8aU77UMBcCezXTmySaGp6F445v8BLSC+zybZQ60AAAAASUVORK5CYII='
        # 将base64字符串转换回二进制数据,并设置为窗口图标
        icon_data = base64.b64decode(icon_base64)
        icon_image = Image.open(BytesIO(icon_data))
        icon_photo = ImageTk.PhotoImage(icon_image)
        root.tk.call('wm', 'iconphoto', root._w, icon_photo)  # 设置窗口图标
        # 设置窗口的背景颜色
        root.configure(bg='white')
        
        img = Image.open(BytesIO(content))
        img = img.resize((350, 350), Image.Resampling.LANCZOS)
        photo = ImageTk.PhotoImage(img)
 
        # 创建一个Frame来放置内容,增加边距效果
        frame = tk.Frame(root, bg='white', padx=20, pady=20)
        frame.pack()
 
        # 创建一个Label显示二维码,并放置到Frame中
        label = tk.Label(frame, image=photo, bg='white')
        label.image = photo  # 保持对photo的引用
        label.pack(pady=(0, 10))  # 在二维码和按钮之间添加一些垂直间距
 
        # 创建一个“已扫码”按钮,点击后关闭窗口,并美化按钮样式
        button = tk.Button(frame, text="已扫码", command=root.destroy, height=2, width=20, bg='#4CAF50', fg='white', font=('Arial', 12, 'bold'))
        button.pack()
 
        # 窗口居中显示
        root.update_idletasks()  # 更新窗口状态,以获取准确的窗口大小
        width = root.winfo_width()
        height = root.winfo_height()
        x = (root.winfo_screenwidth() // 2) - (width // 2)
        y = (root.winfo_screenheight() // 2) - (height // 2)
        root.geometry(f'{width}x{height}+{x}+{y}')  # 设置窗口大小和位置
 
        root.mainloop()
 
    def check_qr_status(self, qrsig, ptqrtoken):
        # 检查二维码登录状态
        print("正在检查二维码状态...")
        while True:
            url = f'https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fqun.qq.com%2Fmanage.html%23click&ptqrtoken={ptqrtoken}&ptredirect=1&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-{time.time()}&js_ver=20032614&js_type=1&login_sig=&pt_uistyle=40&aid=715030901&daid=73&'
            response = self.session.get(url, cookies={'qrsig': qrsig})
            if '二维码已失效' in response.text:
                print('二维码已失效。')
                break
            elif '登录成功' in response.text:
                print('登录成功。')
                return True
            time.sleep(3)
        return False
 
    def verify_group_membership(self, skey, group_id):
        # 验证登录用户是否为指定群组的成员
        print(f"正在验证群组 {group_id} 的成员资格...")
        bkn = self.compute_bkn(skey)
        url = 'https://qun.qq.com/cgi-bin/qun_mgr/get_group_list'
        response = self.session.post(url, data={'bkn': bkn})
        print(response.text)
        groups = re.findall(r'"gc":(\d+),"gn', response.text)
        return group_id in groups
 
if __name__ == '__main__':
    group_id = '722072237'  # 要检查成员资格的QQ群ID
    qq_login = QQGroupLogin()
    qr_content, qrsig = qq_login.fetch_qr_code()
    qq_login.display_qr(qr_content)
    ptqrtoken = QQGroupLogin.compute_ptqrtoken(qrsig)
    if qq_login.check_qr_status(qrsig, ptqrtoken):
        skey = qq_login.session.cookies.get('skey')
        if skey and qq_login.verify_group_membership(skey, group_id):
            print('恭喜您,验证成功!')
        else:
            print('很遗憾,验证失败。')
    else:
        print('登录失败或二维码已失效。')

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景说明
  • 使用效果
  • 参考代码
  • 扫码登录(备份)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档