Python 您所在的位置:网站首页 公众号打卡 Python

Python

2023-12-13 08:40| 来源: 网络整理| 查看: 265

众所周知,因为疫情的原因,很多高校和公司都要求员工每日在微信上进行打卡,来汇报自己的当前身体状态和所处地区。但绝大多数情况下,每天打卡的信息其实是不会变的,我们要做的就是进入公众号——自动登录点进打卡页面——完成打卡,这样重复的操作。

这样的操作在手机上需要花费的时间应该不足一分钟,但依旧每天都会有懒得或者忘了进行操作的人。所以就想到能不能用python写一个脚本,在PC端进行自动打卡呢?

  (本操作仅提供思路参考,大家还是要重视防疫打卡操作)

以下所有操作均以某高校页面为例

 

目录

1.代码前准备

2.代码实现(Cookie+纯requests版本)

3.代码实现(账号密码+Selenium+Requests版本)

4.总结

 

1.代码前准备

由于微信的普及,所以基本各高校和公司每日打卡都是在微信端进行,所以我们需要通过微信找到我们的登录页。

公众号进入打卡页面标题

 

标题选择复制链接地址

 

我们最终希望用Requests模拟发包登录,而平时都是直接用微信进行自动登录。显然在只用脚本的情况下没办法实现微信自动登录跳转,所以我们需要先找到能输入账号密码的页面。(此时没有用Cookie是因为实验之后发现,Cookie有效期不到2小时,没办法支撑每日用同一个Cookie登录打卡)

此时,我们通过PC微信找到该链接:http://****app.i****.info/NYDXY/#/,但是如果直接用浏览器打开该链接,会跳转”请用微信客户端打开链接“的页面。

标题直接用浏览器打开出错

 

因此,需要想办法绕过该限制,思路有两个:1.通过Fiddler等抓包软件,找找有没有其他登录页面。2.模拟微信浏览器的请求头和Cookie进入。但是正如前文所说,经过尝试思路2,确实能够完成全流程,但该页面Cookie有效期很短,没办法每日均进行自动打卡,因此我们选择尝试思路1,还是通过账号密码登录。

沿着思路1,我们打开Fiddler,启动抓包。然后回到PC微信,和刚才同样的操作进入打卡页面自动登录,再回到Fiddler,发现刚才进入打卡页面的所有操作已经被记录在软件里了。接下来就是通过url和请求头等信息,来判断是否存在其他的登录页面。

红框所示为抓包所得

 

经过分析和尝试,前两个链接都会提示400或其他错误,但尝试到第三个链接时,会跳转到学校的统一登陆页面,同时还在下方发现微信快捷登录图表。通过该页面输入账号密码后,浏览器自动跳转到了我们所需的打卡页面了。此时,我们实现了PC端模拟登录微信打卡页面。

统一登录页面

 

浏览器成功登入打卡页面

 

第二步,我们需要看我们打卡到底在浏览器端是如何完成的。在手动进行打卡操作之后,经过浏览器的F12,看到有四个php提供了post操作,而通常我们的表单数据都是由post方法完成的。排除掉之前就存在的第一二个php,所以我们强烈怀疑就是通过这剩余两个php完成的打卡操作。

怀疑的jump.php

具体来看发现,最后一个jump.php实际上返回的是个人基本信息,以供自动填充用的,提交的表单也与打卡无关。

最后的jump.php返回的结果

 

但到了倒数第二个jump.php,通过其提交的Form数据,我们发现就是通过这个php我们完成了打卡操作。因此得知,我们的最终目标,就是通过该php来完成我们的自动打卡。至此,我们的代码前分析全部完成,接下来进入代码环节。

倒数第二个php提交的表单

 

2.代码实现(Cookie+纯requests版本)

( 此版本使用requests包进行python代码实现)

因为我们已经通过浏览器进行过登录,获得了Cookie,所以我们先尝试通过Cookie进行直接打卡。先通过浏览器F12获得Cookie和其余请求头,然后根据需要放在Python文件中。(这里的请求头大家可以选择需要的来放,一般加上Cookie和User-Agent即可,如果失败还可以尝试将User-Agent换为Android或ios的模拟请求)

右侧为请求头

 

headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36', 'Cookie': '浏览器上找到的Cookie' }

然后再根据From Data的数据,按照字典格式一一放进Python文件中去。

From Data数据

 

Python文件格式

 

最后再尝试post即可。发现最后返回值和浏览器返回值相同,打卡成功。

url = 'http://****app.i****.info/jinzhi/jump.php' s = requests.session() response = s.post(url=url, headers=headers, data=data) response.encoding = 'utf-8' print(response.text) Python返回值

 

浏览器返回值

 

3.代码实现(账号密码+Selenium+Requests版本)

    

前文已经实现在知道Cookie的前提下,可以直接通过固定php页面进行表单上传打卡。但是由于Cookie有效期极短,所以我们明显需要有一个每次打卡前自动获取Cookie的方法。

回到一开始的Login页面,同样我们通过F12抓包,看每次登录时提交的表单具体值有些什么。在用户名和密码,我们尝试性的输入123456之后点击提交,会发现在login文件下会POST一个表单,里面所包含的就是每次登录要传给服务器的信息了。

登录信息

 

但是从表单我们看到,除了我们填写的账号密码,还有包括lt,execution等信息。经过查找,我们发现这些信息是在加载网页时就自动生成的,所以我们可以通过request.session()的方法进入页面后,再通过正则表达式将所需信息找出来,和账号密码一起形成表单。

页面隐藏的元素

 

但是我们还可以看到,password明显是经过加密处理后的信息,所以我们不能直接明文提交密码,要想办法将密码进行处理。而这个加密后的密码,是我们点击提交后网页自动将我们的明文密码进行的加密,所以大概率就是一个js的处理,因此需要找到网页上加密的js文件。查找login页面和js之后,最终找到是encrypt.js这个文件完成了明文密码的加密。

加密js

 

按逻辑来说,我们此时就可以查找传递该js所需参数,得到加密后的密码,连同其他信息一起post给login就可以完成我们的登录和cookie获取了。但是这个js真是又长又混淆,以现在的水平暂时不能找到其所需参数。所以换了个思路,通过Selenium来模拟登录,直接获取Cookie。

(这里如果可以看懂这个js加密的话,是完全可以不依靠Selenium获取Cookie的,大家有兴趣可以尝试一下)

Selenium就比较简单了,通过分析登录页面,找到需要Input的地方,获取Xpath,再通过Selenium填写,并获取Cookie就可以了。

通过F12得到元素的Xpath

 

def get_cookie(url_, user_): driver = webdriver.Chrome() driver.get(url_) driver.find_element_by_xpath('//*[@id="username"]').send_keys(user_['name']) driver.find_element_by_xpath('//*[@id="password"]').send_keys(user_['password']) driver.find_element_by_xpath('//*[@id="casLoginForm"]/p[4]/button').click() sleep(3) cookie_ = driver.get_cookies()[0] driver.quit() return cookie_['name']+'='+cookie_['value']

获取cookie后,和之前操作相同,提交表单即可,完整代码如下。

import requests from selenium import webdriver from time import sleep def get_cookie(url_, user_): driver = webdriver.Chrome() driver.get(url_) driver.find_element_by_xpath('//*[@id="username"]').send_keys(user_['name']) driver.find_element_by_xpath('//*[@id="password"]').send_keys(user_['password']) driver.find_element_by_xpath('//*[@id="casLoginForm"]/p[4]/button').click() sleep(2) cookie_ = driver.get_cookies()[0] driver.quit() return cookie_['name']+'='+cookie_['value'] user = {'name': '', 'password': ''} cookie = get_cookie('https://authserver.*****.edu.cn/authserver/login?service=http://*****app.i*****.info/jinzhi/index.php', user) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36', 'Cookie': cookie } data = { 'mymethod': 'POST', 'myurl': 'https://*****api.*****.edu.cn/api/v1/ncp/student/daka/update', 'id': '', 't1': '否', 't2': '', 't3': '否', 'stsfyc': '否', 'stsfycxq': '', 'dqszdpro': '{"code":""}', 'dqszdcity': '{"code":""}', 'dqszdreg': '{"code":""}', 'sfdgyq': '否', 'dgyqqt': '[]' } url = 'http://*****app.i*****.info/jinzhi/jump.php' s = requests.session() response = s.post(url=url, headers=headers, data=data) html = response.text print(html) 4.总结

其实在类似需求中,代码部分相对而言占比更少,重要的地方在于找到提交的表单数据和页面链接,和能否完成加密解密。本文由于js加密的限制,只能通过Selenium来获取Cookie进而实现表单提交。在之后的版本中,希望能够通过分析js文件,完成参数传递加密,最终只用Requests包完成打卡操作。

与本文类似的应用场景还有很多,都可以用相同的思路去解决,本文作为供大家选择的参考,如果各位读者有更好的思路欢迎多多交流。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有