一、 实现原理
通过定时向健康系统的页面发送一个请求,请求的内容为每次打卡需要的信息。就可实现自动打卡
二、获取请求的内容
通过抓包软件抓取,手机上面主要使用的是小黄鸟——HttpCanary 抓取信息,电脑上面主要是通过Fiddler软件。抓取易校园的数据,找到有关https://h5.xiaofubao.com/marketing/health/getDetail 链接的请求,然后里面会存在一条关于url文件,url解码即可得到自己发送请求时发送的内容
可以看到抓取到的信息解码后是(只展示了解码后的一部分)
可以发现,传递的内容就是就是你的个人信息。接下来就是将这些内容发送到指定的位置
三、发送请求
将请求的内容,发送到健康系统的那个页面
1. 发送方式
发送请求的方式主要的方式是通过python中的一个requests库。
request库方法介绍
方法 | 说明 |
---|---|
requests.request() | 构造一个请求,支撑一下各方法的基础方法 |
requests.get() | 获取HTML网页的主要方法,对应于HTTP的GET |
requests.head() | 获取HTML网页头信息的方法,对应于HTTP的HEAD |
requests.post() | 向HTML网页提交POST请求的方法,对应于HTTP的POST |
requests.put() | 向HTML网页提交PUT请求的方法,对应于HTTP的PUT |
requests.patch() | 向HTML网页提交局部修改请求,对应于HTTP的PATCH |
requests.delete() | 向HTML页面提交删除请求,对应于HTTP的DELETE |
由于在抓取的数据时,发现易校园主要采用的时post的请求方式,所以这里要使用到的是post方法
requests.put(url, data=None, **kwargs)
- url:拟更新页面的url链接
- data:字典、字节序列或文件,Request的内容
- **kwargs:12个控制访问参数
也就是说通过下面的方式就可以发送请求
requests.post(url, data= "传递的内容")
2.转换格式
可以看到前面传递内容的data采取的是一个字典的格式,字典就是键值对(一个键对应一个数值),所以需要把上面url内容转换成下面这种格式,才能发送内容
转换的话有两种解法:
(1)自己一个一个的手动修改成字典的形式,这样的话就很费时费力
(2)写脚本
这里我采用第二种,脚本不唯一,下面的只是一种思路
(1)将&转换成回车
首先查看两者的区别, 字典中没有&, 而且&是作为一组键值对的分界
利用python中正则表达式的一个方法sub, 来将&替换成回车
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
sub方法:实现正则的替换
函数原型:re.sub(pattern, repl, string, count=0, flags=0)
- pattern : 正则中的模式字符串。
- repl : 替换的字符串,也可为一个函数。
- string : 要被查找替换的原始字符串。
- count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
- flags : 编译时用的匹配模式,数字形式。
其中前三个为必选参数,后两个为可选参数。
这里利用的方式:
data_str = re.sub(r'&', '\n', info_daka) # 其中 info_daka 表示的是你url解码以后的内容,data_str表示转换的内容
将&换成 回车
目前已经被修改成了:
(2)转换成多个元组
利用正则表达式的findall方法将上面的data_str转换成元组(类似于列表,不了解就当作C语言的数组)
findall方法:
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表。
注意: match 和 search 是匹配一次 findall 匹配所有。
语法格式为:
findall(string[, pos[, endpos]])
- string : 待匹配的字符串。
- pos : 可选参数,指定字符串的起始位置,默认为 0。
- endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
content = re.findall(r'(.*?)=(.*)', data_str)
这里重点讲一下‘(.*?)=(.*)’的作用,
首先先看 不加() 的情况。其中的?表示非贪婪模式,它会自动匹配最少的内容,一般情况默为贪婪模式。匹配更多的情况
可以发现它是以回车键为截断的,首先它会将回车键的前部分转换成元组的一个元素,然后将后面的name作为一个元素,放到第二位
但是加上一个()以后就发生了变化
?就是不贪婪了,前一个括号里不会有等号
从前往后,找到的第一个等号,就作为划分,后面全部算等号右边的值,包括又出现等号的情况,因为后面是贪婪匹配
这里理解可能还存在问题
那么此时的content里面的内容为:
(3)最终转换成字典
最终再通过for循环每一个元组将元素提取出来形成字典,i表示每一个元组,第一个元组:key=id,vaule为id的值
for i in content:
key = i[0]
value = i[1]
sign_data[key] = value
3. 数据修改
(1)说明
上面的转换成了字典,但是还有一些内容是实时的需要修改,这里我只修改了其中的两项
(2)打卡时间的修改
利用python中的time库的strftime方法实现当前的时间
datatime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
然后直接利用update修改字典里面的键对应的值即可
sign_data.update({'updateTime': datatime})
(3)经纬度的修改
这个经纬度其实可改可不改
num1 = random.randrange(100, 999)
num2 = random.randrange(100, 999)
addres = re.findall('(\d{3}\.\d{3})\d*,(\d{2}\.\d{3})', sign_data['longitudeAndLatitude'])
sign_data['longitudeAndLatitude'] = f'{addres[0][0]}{num1},{addres[0][1]}{num2}'
前面两行代码表示随机生成随机数
第三行代码表示减小精度,
第四行代码表示在最后几位数上随机生成几个数,以此来造成变化
4. 全部代码
# -*- coding:utf-8 -*-
import re
import time
import random
import requests
datatime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
num1 = random.randrange(100, 999)
num2 = random.randrange(100, 999)
info_daka = ''
def main(*args):
sign_url = 'https://h5.xiaofubao.com/marketing/health/doDetail'
data_str = re.sub(r'&', '\n', info_daka)
content = re.findall(r'(.*?)=(.*)', data_str)
sign_data = {}
for i in content:
key = i[0]
value = i[1]
sign_data[key] = value
# print(sign_data)
addres = re.findall('(\d{3}\.\d{3})\d*,(\d{2}\.\d{3})', sign_data['longitudeAndLatitude'])
sign_data[
'longitudeAndLatitude'] = f'{addres[0][0]}{num1},{addres[0][1]}{num2}'
sign_data.update({'updateTime': datatime})
print(sign_data)
res_sign = requests.post(url=sign_url, data=sign_data)
print(res_sign.text)
# 云函数入口
def main_handler(event, context):
main()
if __name__ == '__main__':
main()
四、自动化运行脚本
上面的脚本虽然实现了内容的传递的方式,但是仍然需要运行脚本才能发送请求,如果每次打卡都需要运行脚本的话,那么所做的将毫无意义。采取的方式是,利用腾讯云的云函数,利用里面的定时触发器,每日定时打卡。
在使用之前,需要在代码中添上两行代码作为云函数的入口
# 云函数入口
def main_handler(event, context):
main()
接下来就是注册一个腾讯云账号,进入腾讯云函数网址https://console.cloud.tencent.com/scf/list
(1)新建函数,选择从头开始,
(2)在高级配置中修改执行超过时间
(3)在触发配置中选择自定义创建,具体要实现的情况自己选择,也可以直接确定
(4)在函数管理中,将前面的代码写进去,然后再测试,部署即可
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮箱至 1627319559@qq.com