下载地址:https://www.pan38.com/share.php?code=JCnzE 提取密码:7789
这个QQ资料查询器包含四个主要模块:核心爬虫模块、Flask API接口、命令行交互界面和依赖文件。核心模块实现了QQ登录、信息获取和解析功能,API接口提供了HTTP服务,命令行界面提供了交互式查询体验。使用时需要先扫码登录获取cookie,然后才能查询QQ资料信息。
import requests
import json
import time
from datetime import datetime
import hashlib
import random
class QQInfoSpider:
def __init__(self):
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Referer': 'https://user.qzone.qq.com/'
}
self.session = requests.Session()
self.cookies = {}
def get_ptqr_token(self):
url = "https://ssl.ptlogin2.qq.com/ptqrshow"
params = {
'appid': '549000912',
'e': '2',
'l': 'M',
's': '3',
'd': '72',
'v': '4',
't': str(random.random())
}
response = self.session.get(url, params=params)
self.cookies.update(response.cookies.get_dict())
return response.content
def check_qr_login(self):
url = "https://ssl.ptlogin2.qq.com/ptqrlogin"
params = {
'u1': 'https://qzs.qq.com/qzone/v5/loginsucc.html',
'ptqrtoken': self._get_ptqr_token_hash(),
'ptredirect': '0',
'h': '1',
't': '1',
'g': '1',
'from_ui': '1',
'ptlang': '2052',
'action': '0-0-' + str(int(time.time() * 1000)),
'js_ver': '22052613',
'js_type': '1',
'login_sig': '',
'pt_uistyle': '40',
'aid': '549000912',
'daid': '5',
'pt_3rd_aid': '0'
}
response = self.session.get(url, params=params)
return response.text
def _get_ptqr_token_hash(self):
qrsig = self.cookies.get('qrsig', '')
e = 0
for c in qrsig:
e += (e << 5) + ord(c)
return 2147483647 & e
def get_cookie_after_login(self, redirect_url):
response = self.session.get(redirect_url)
self.cookies.update(response.cookies.get_dict())
return self.cookies
def get_qq_info(self, qq_number):
url = f"https://r.qzone.qq.com/fcg-bin/cgi_get_portrait.fcg"
params = {
'uins': qq_number,
'g_tk': self._get_g_tk(),
'format': 'jsonp'
}
response = self.session.get(url, params=params, headers=self.headers)
data = response.text[len('_Callback('):-2]
return json.loads(data)
def _get_g_tk(self):
skey = self.cookies.get('skey', '')
hash_val = 5381
for c in skey:
hash_val += (hash_val << 5) + ord(c)
return hash_val & 0x7fffffff
def parse_qq_info(self, raw_data, qq_number):
info = raw_data.get(str(qq_number), {})
result = {
'qq': qq_number,
'nickname': info.get('nickname', '未知'),
'gender': '男' if info.get('gender', 0) == 1 else '女',
'age': self._calculate_age(info.get('birthday', '')),
'level': info.get('level', 0),
'vip_level': info.get('vip_level', 0),
'online_status': self._parse_online_status(info.get('online', 0)),
'register_days': self._calculate_register_days(info.get('regdate', 0)),
'last_login': self._format_timestamp(info.get('last_login', 0)),
'qzone_visits': info.get('qzone_visits', 0),
'signature': info.get('signature', '无')
}
return result
def _calculate_age(self, birthday):
if not birthday or len(birthday) != 8:
return '未知'
year = int(birthday[:4])
current_year = datetime.now().year
return current_year - year
def _parse_online_status(self, status_code):
status_map = {
0: '离线',
1: '在线',
2: '隐身',
3: '忙碌',
4: '离开',
5: 'Q我吧'
}
return status_map.get(status_code, '未知')
def _calculate_register_days(self, reg_timestamp):
if not reg_timestamp:
return '未知'
reg_date = datetime.fromtimestamp(reg_timestamp)
delta = datetime.now() - reg_date
return delta.days
def _format_timestamp(self, timestamp):
if not timestamp:
return '未知'
return datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
flask import Flask, request, jsonify
from qq_info_spider import QQInfoSpider
import threading
app = Flask(__name__)
spider = QQInfoSpider()
lock = threading.Lock()
@app.route('/api/qq/info', methods=['GET'])
def get_qq_info():
qq_number = request.args.get('qq')
if not qq_number or not qq_number.isdigit():
return jsonify({'error': 'Invalid QQ number'}), 400
try:
with lock:
# Step 1: Get QR code for login
qr_image = spider.get_ptqr_token()
# Step 2: Wait for QR code scan
login_result = spider.check_qr_login()
while '二维码未失效' in login_result:
time.sleep(2)
login_result = spider.check_qr_login()
if '登录成功' not in login_result:
return jsonify({'error': 'QR login failed'}), 401
# Step 3: Get cookies after login
redirect_url = login_result.split("'")[1]
spider.get_cookie_after_login(redirect_url)
# Step 4: Get QQ info
raw_data = spider.get_qq_info(qq_number)
parsed_info = spider.parse_qq_info(raw_data, qq_number)
return jsonify(parsed_info)
except Exception as e:
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
argparse
from qq_info_spider import QQInfoSpider
import time
import sys
def display_qq_info(info):
print("\n=== QQ 资料查询结果 ===")
print(f"QQ号码: {info['qq']}")
print(f"昵称: {info['nickname']}")
print(f"性别: {info['gender']}")
print(f"年龄: {info['age']}")
print(f"等级: {info['level']}")
print(f"VIP等级: {info['vip_level']}")
print(f"在线状态: {info['online_status']}")
print(f"注册天数: {info['register_days']}天")
print(f"最后登录: {info['last_login']}")
print(f"空间访问量: {info['qzone_visits']}")
print(f"个性签名: {info['signature']}")
print("=====================\n")
def main():
parser = argparse.ArgumentParser(description='QQ资料查询工具')
parser.add_argument('qq', type=str, help='要查询的QQ号码')
args = parser.parse_args()
spider = QQInfoSpider()
try:
print("正在获取登录二维码...")
qr_image = spider.get_ptqr_token()
with open('qq_qr.png', 'wb') as f:
f.write(qr_image)
print("二维码已保存为 qq_qr.png,请使用手机QQ扫码登录")
print("等待扫码登录...")
login_result = spider.check_qr_login()
while '二维码未失效' in login_result:
time.sleep(2)
login_result = spider.check_qr_login()
if '登录成功' not in login_result:
print("登录失败:", login_result)
sys.exit(1)
print("登录成功,正在获取QQ信息...")
redirect_url = login_result.split("'")[1]
spider.get_cookie_after_login(redirect_url)
raw_data = spider.get_qq_info(args.qq)
parsed_info = spider.parse_qq_info(raw_data, args.qq)
display_qq_info(parsed_info)
except Exception as e:
print("发生错误:", str(e))
sys.exit(1)
if __name__ == '__main__':
main()
requests==2.31.0
Flask==3.0.0
python-dateutil==2.8.2
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。