文章目录
前言
博主推更新总是有原因的, 开始了如下狡辩, 比如刚入手部署了两台服务器发现服务器有 y i 些些问题, 又比如一键部署的开源项目硬着头皮当英语读代码这件事, 又比如我好像是学算法来着但是从暑假到现在没学过算法一样, 杨紫, 时间总是过的很快的, 作为一个 ACMER 又马上寒假,
我的算法还没学啊
在别的ACMER 学算法的时候我在努力打螺丝属实这个逻辑了
重点是, 博主又又叕来爆肝了, 总有小伙伴催促博主改进和学习, 总有人生的无常和大肠包小肠, 总有为爱发电的博主看不到早上升起的太阳, 在月光犀利中独自前行…
正文
详细步骤分析
Python
抓包进阶, 识别并且分析网络请求- 可以配合
Python QQ 机器人
交互使用, 充当前端部分- 轻量级数据库
sqlite3
存储用户资料- 服务器 ( 这里以
ubuntu
系统为例 )Crontab
的定时任务
建议在上述知识点
有一定了解的前提食用本篇博客
Python 抓包部分
一. 分析网络请求
承接第一期, token 会更新了, 不能使用简单的烹饪手法了,我也是最近学习 springbot + vue 的 oj 搭建才突然发现, 这个 api 可以溯源啊
Charles 配置好后看到如下目录, 找到一个 api
看到
Charles
里的一堆, 把根网址拿出来, 在浏览器访问一下
一 个 e 学生管理系统
随便点击
学籍档案
把, 有个二维码登录, 扫之后发现进入了一个学生管理中心, 但是好像找不到Token
, 这是的博主也不知道其中的联系
在学长的指点下, 博主被迫看完了微信的 y i 些开发文档, 发现上文的
token
和这里有 y i 点点相似, 有但是不懂
最后在另一位博主大大的启发下, 发现这个二维码的作用是获取微信的授权信息
登录有两个简单步骤
- 微信小程序
服务端
生成有唯一uuid
的二维码, 用户 ( 客户端 ) 扫码获取微信授权服务端
端口检查, 获取微信授权中携带的用户的认证信息
分析结论
实际使用中发现, 微信小程序为了功能使用, 在一直访问服务的过程中 ,
微信授权信息
不会失效
简而言之, 获取微信授权 ( 扫码 ) , 并且微信小程序检查 ( Qrcheck ) 后, 网页活动 ( 响应 ) , 三点同时满足就能随时访问服务 ( 个人信息 )
Cookie 代替 Token
cookies 的作用是在本地保存用户的登录 ( 授权 ) 信息, 可以用这个保持客户端的活动 ( 响应 )
二. 解析并保存二维码
- 按需所求, 找到二维码
- 找到二维码的请求时候, 小伙伴们肯定有 y i 点点懵, 这个二维码额
重点
按照上文的说法, 我们只需要获取二维码的uuid
加上网络的请求网址反向解析就能把二维码爬取下来
- 有点网络经验的小伙伴肯定会推测出, 这个
uuid
就在网页的body
里
这里博主照顾大部分小伙伴一步步来
- 找到
data-qrcode
获得申请二维码uuid的网址
, 那一长串地址
- 这里用网页自带的
F12
, 在NetWork
找到出现二维码的网页请求, 找到我们需要的Cookie
- 简单获取
申请二维码uuid的网址
,uuid
和cookie
import requests
import qrcode
import re
HEALTHY_DOWNLOAD = "" # 二维码保存地址
url = "" # 看到二维码的网络链接
response = requests.get(url)
# cookies 中的用户信息, Qrcheck检测成功后为用户临时密码
PHPSESSID = re.findall("PHPSESSID=(.*?);", str(response.headers))[0]
# QRcodeuuid 信息用于获取 qrcode 的检测结果
QRcodeuuid = re.findall("data-uuid=\"(.*?)\"", str(response.text))[0]
# 获取二维码链接
url = re.findall("data-qrcode=\"(.*?)\"", str(response.text))[0]
# 二维码生成
img = qrcode.make(url)
# 二维码保存
img.save(HEALTHY_DOWNLOAD)
三. 分析Qrcheck所需的元素
- 常规方式
宁多不少, 在Headers
和Payload
里尝试选择有用信息
博主直接将有用的信息在下图标出了
url
,cookie
,x-requested-with
- 二维码的
uuid
- 简便方法
找到cUrl ( bash )
, 用分析工具解析网络请求获取python
代码
Qrcheck, 成功后 会返回用户登录的
cookie
信息,其结构如下
cookie = {
# 之前二维码中PHPSESSID 的微信授权的临时密码, 会失效
'PHPSESSID': '',
# 微信授权成功获取的用户唯一标识
'stoken': ''
}
Qrcheck 大概会持续 3 分钟, 检测登录成功代码如下
from datetime import datetime
import requests
import re
def check_link(Cookies, QRcodeuuid):
""" PHPSESSID 为二维码扫描时获得,登录成功后为用户临时密码"""
try:
# 成功状态
"""{"code":0,"msg":"","time":1669872758,"data":{"status":3,"msg":"授权登录成功"}}"""
# 失败状态
"""{"code":0,"msg":"","time":1669872942,"data":{"status":4,"msg":"二维码已过期, 请重新生成二维码扫码登录"}}"""
# 初始状态 二维码已过期
status = 4
st = datetime.now()
while status != 3:
# 等待登录暂停时间
time.sleep(5)
# 请求头
cookies = {'PHPSESSID': PHPSESSID}
data = {'uuid': QRcodeuuid}
headers = {
"x-requested-with": "XMLHttpRequest"
}
url = "" # 二维码检查链接
# 检查登录状态
response = requests.post(url=url, headers=headers, cookies=cookies, data=data)
# 登录检查的状态
status = int(re.findall("\"status\":(.*?),", response.text)[0])
duringtime = (datetime.now() - st).seconds
if status == 3:
Cookies = response.cookies.get_dict()
break
if duringtime > 1500: # 请求时间大于 3 分钟, 二维码过期
break
# 返回检查成功后的用户登录Cookies
return status, Cookies
except Exception as e:
# 返回错误信息
return e, Cookies
Sqlite3 数据库
一. 分析数据规模和类型
对于少量用户,百量不到千级别的数据量,Sqlite3 是个不错的选择,安装配置使用及其简单
表结构
列名 | 信息 |
---|---|
用户的QQ号 | |
status | 请求状态 ( 默认不发送,审核用户阶段 ) |
stoken | 用户的临时Cookie |
PHPSESSID | 用户的Cookie唯一标识 |
version | 选择收信方式 ( 默认不发送 ) |
邮箱功能在第一期有提, 也可配合qq机器人使用
基本操作
mysql
的大部分sql
操作都可以用
- 建表操作, 不存在则会创建
create table if not exists healthydaily( "QQ" varchar(20) NOT NULL primary key , "status" int default 0, "stoken" varchar(100) DEFAULT NULL, "PHPSESSID" varchar(100) DEFAULT NULL, "version" int default 0);
- 查询操作
select * from healthydaily;
- 插入操作
insert into healthydaily values("", 0, "","", 0);
python
代码操作数据库
import sqlite3
def loading_cookie(Cookies, QQ):
"""Cookies 为字典,可为 Qrcheck 的范围值"""
# 如果文件不存在,会在当前目录创建:
conn = sqlite3.connect('healthydaily.db')
# 创建一个Cursor:
cursor = conn.cursor()
# 执行一条SQL语句,创建healthydaily表, 不存在则会创建
cursor.execute('create table if not exists healthydaily( "QQ" varchar(20) NOT NULL primary key , "status" int default 0, "stoken" varchar(100) DEFAULT NULL, "PHPSESSID" varchar(100) DEFAULT NULL, "version" int default 0);')
cursor.execute(sql)
# 执行插入操作
sql = 'insert into healthydaily values( "{}", 0, "{}","{}", 0);'.format(QQ,Cookies["stoken"],Cookies["PHPSESSID"])
cursor.execute(sql)
# 关闭Cursor:
cursor.close()
# 提交事务:
conn.commit()
# 关闭Connection:
conn.close()
二. Sqlite3 的安装使用
- Windows 系统, 用
pip
安装包
pip install pysqlite3
- Unbuntu 系统
- 更新安装包
sudo apt-get update
- 安装
Sqlite3
sudo apt-get install sqlite3
- 查看是否安装成功
sqlite3 --version
- 安装 python 对
Sqlite
的支持包
sudo apt-get install python-pysqlite2
Ubuntu 定时任务
一般系统自带
crontab
一. 基本操作
- 查看是否启动
ps -ef | grep cron
- 查看定时任务
sudo crontab -l
- 添加定时任务
sudo crontab -e
cookie
保活操作
每隔二十分钟运行一次 healthy_daily_keep.py 相当于用户访问一次学生管理系统来保活
cookie
, 将日志文件输出到 healthydaily_keep.log
*/20 * * * * python3 /根目录/healthy_daily_keep.py >> /根目录/healthydaily_keep.log 2>&1
二. 实现思路
- 每天早上七点发送请求
import requests
def send_misson(Cookies):
"""Cookies 传入字典形式"""
# 地址
data = {} # 自行抓包
respense = requests.post("日报网址", data=data, cookies=Cookies)
message = str(respense.json()['msg'])
if message == "You are logged expired":
message = "状态失效, 请重新扫码!"
return message
- 每隔二十分钟去申请访问一下学生管理系统网页
import requests
def get_cookies():
# 如果文件不存在,会在当前目录创建:
conn = sqlite3.connect('healthydaily.db')
# 创建一个Cursor:
cursor = conn.cursor()
# 保活请求, status 为 1
sql = "select stoken,PHPSESSID,QQ from healthydaily where status=1"
# 继续执行一条SQL语句,插入一条记录:
cursor.execute(sql)
date_list = cursor.fetchall()
# 关闭Cursor:
cursor.close()
# 提交事务:
conn.commit()
# 关闭Connection:
conn.close()
# 返回 cookie 信息
return date_list
def connect_keep():
datalist = get_cookies()
for data in datalist:
try:
Cookies = {'PHPSESSID': data[1], 'stoken': data[0]}
# 扫码后获取的cookies信息
day = requests.session()
# 清空 cookies 信息, 用于多用户的并发
day.cookies.clear()
# 携带 cookies 信息访问
day.cookies.set("PHPSESSID", Cookies["PHPSESSID"])
day.cookies.set("stoken", Cookies["stoken"])
# 访问用户中心保活 PHPSESSID
response = day.get(url="学生信息管理系统")
# print(response.text)
status = re.findall(">微信扫码登录<", response.text)
# print(status)
if status == []:
print("{} 上传成功".format(data[2]))