高考分数查询结果自动推送至微信(卷II)
祝各位端午节安康!只要心中无结,每天都是节,开心最重要!
在上一篇文章高考分数查询结果自动推送至微信(卷Ⅰ)-CSDN博客中谈了思路,今天具体实现。文中将敏感信息已做处理,读者根据自己的实际情况替换。
主要逻辑:
- 轮询接口列表;
- 提取IP和端口;
- 替换查询接口的IP和端口;
- 替换验证码接口的IP和端口;
- 检测可达性;
- 成功查询后保存结果并推送消息,跳出循环。
某省去年放出的查询接口主页
主页源码中与查询入口有关的网页源码(部分)
<ul class="cfrk"><li> <a href="http://xxx.xxx.xxx.xxx:81/n_score/index.jsp" class="gkcj-btn">入口一</a></li><li> <a href="http://xxx.xxx.xxx.xxx:82/n_score/index.jsp" class="gkcj-btn">入口二</a></li><li><a href="http://xxx.xxx.xxx.xxx:81/n_score/index.jsp" class="gkcj-btn">入口三</a></li><li> <a href="http://xxx.xxx.xxx.xxx:83/n_score/index.jsp" class="gkcj-btn">入口四</a></li><li><a href="http://xxx.xxx.xxx.xxx:81/n_score/index.jsp" class="gkcj-btn">入口五</a> </li>中间省略若干行......<li> <a href="http://xxx.xxx.xxx.xxx:86/n_score/index.jsp" class="gkcj-btn">入口十六</a></li>
</ul>
我们从上面接口列表中提取IP和端口,检测可达性,自动查询分数,然后推送微信。
完整程序
# coding=utf-8
import requests
from bs4 import BeautifulSoup
import time
import itertools
import json
import random
import ddddocr
import onnxruntime
import schedule# 设置日志级别用于去除ddddocr广告
onnxruntime.set_default_logger_severity(3)# 你的 Server 酱 SCKEY
SERVER_CHAN_SCKEY = 'YOUR_SERVER_CHAN_SCKEY' # 替换成你的 SCKEYdef imgRecognition(img):"""识别验证码图片内容:param img: 图片文件路径:return: 返回识别结果字符串,如果失败则返回None"""try:ocr = ddddocr.DdddOcr()with open(img, 'rb') as f:img_bytes = f.read()res = ocr.classification(img_bytes)return resexcept Exception as e:print(f"OCR failed: {e}")return Nonedef getVerifyimagepage(session, headers, cookies, captcha_url):"""获取验证码图片并保存为 img.jpg:param session: requests.Session 对象:param headers: 请求头信息:param cookies: 请求时带的Cookie:param captcha_url: 验证码URL:return: 无"""time.sleep(random.random())t = random.uniform(0.0, 1.0)params = {'rnd': t,}try:res = session.get(captcha_url, headers=headers, params=params, cookies=cookies, verify=False)with open('img.jpg', 'wb') as img:img.write(res.content)except Exception as e:print(f"Failed to get image: {e}")def get_Kaptcha(session, headers, cookies, captcha_url):"""获取验证码图片并进行识别:param session: requests.Session 对象:param headers: 请求头信息:param cookies: 请求时带的Cookie:param captcha_url: 验证码URL:return: 返回识别结果字符串,如果失败则返回None"""getVerifyimagepage(session, headers, cookies, captcha_url)return imgRecognition('img.jpg')def get_query_endpoints(session, base_url):"""获取包含查询接口的URL列表:param session: requests.Session 对象:param base_url: 主页URL:return: 返回查询接口URL列表,如果获取失败则返回空列表"""try:response = session.get(base_url)response.raise_for_status()html_content = response.textsoup = BeautifulSoup(html_content, 'html.parser')ul_tag = soup.find('ul', class_='cfrk')if ul_tag:return [a['href'] for a in ul_tag.find_all('a')]else:print("No query endpoints found.")return []except requests.RequestException as e:print(f"Failed to get query endpoints: {e}")return []def extract_ip_port(url):"""从URL中提取IP和端口部分:param url: 完整URL:return: 返回IP和端口字符串,如果提取失败则返回None"""parts = url.split('/')if len(parts) > 2:return parts[2]return Nonedef ping_website(session, full_url):"""检查网站的可达性:param session: requests.Session 对象:param full_url: 完整网站URL:return: 网站可达返回True,否则返回False"""try:response = session.head(full_url)return response.status_code == 200except requests.RequestException as e:print(f"Request failed: {e}")return Falsedef send_to_wechat(message):"""通过 Server 酱发送消息到微信:param message: 要发送的消息文本:return: 返回响应的JSON数据,如果发送失败则返回None"""url = f'https://sc.ftqq.com/{SERVER_CHAN_SCKEY}.send'data = {'text': '查询结果通知','desp': message}try:response = requests.post(url, data=data)response.raise_for_status()return response.json()except requests.RequestException as e:print(f"Failed to send message: {e}")return Nonedef perform_query(session, headers, cookies, query_url, idNumber, ticketNumber, captcha_url):"""执行具体的查询任务:param session: requests.Session 对象:param headers: 请求头信息:param cookies: 请求时带的Cookie:param query_url: 查询接口URL:param idNumber: 身份证号:param ticketNumber: 准考证号:param captcha_url: 验证码URL:return: 返回查询结果的JSON数据,如果查询失败则返回None"""randCode = get_Kaptcha(session, headers, cookies, captcha_url)if randCode is None:print("Failed to get CAPTCHA code.")return Nonequery_full_url = f'{query_url}?idNumber={idNumber}&ticketNumber={ticketNumber}&randCode={randCode}'try:response = session.get(query_full_url, headers=headers, cookies=cookies)response.raise_for_status()return response.json()except requests.RequestException as e:print(f"Query failed: {e}")return Noneterminate = False # 终止程序标志def job():"""每分钟执行一次的任务,用于进行查询并处理结果:return: 无,但当查询成功并发送消息后,会返回return schedule.CancelJob取消定时任务"""global terminatefor full_url in url_cycle:ip_port = extract_ip_port(full_url)if ip_port:base_query_url = base_query_url_template.format(ip_port)captcha_url = base_captcha_url_template.format(ip_port)if ping_website(session, full_url):print(f"{full_url} is reachable")# 动态设置 headers 中的 Referer 和 Hostheaders["Referer"] = f"http://{ip_port}/n_score/"headers["Host"] = ip_portresult = perform_query(session, headers, cookies, base_query_url, idNumber, ticketNumber, captcha_url)if result:print("Query success:", result)score_text = json.dumps(result, ensure_ascii=False, indent=4)json_path = 'result.json'with open(json_path, 'w') as json_file:json.dump(result, json_file, ensure_ascii=False, indent=4)response = send_to_wechat(score_text)if response and response.get('message') == '':print("信息发送成功")terminate = Truereturn schedule.CancelJob # 成功后返回取消任务else:print("发送信息失败!")else:print("查询失败")break # 无论成功还是失败,都跳出循环else:print(f"{full_url} 暂时不能访问!")else:print(f"IP、端口错误 {full_url}")# 初始化配置
session = requests.Session()
headers = {"Accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8","Accept-Encoding": "gzip, deflate","Accept-Language": "zh-CN,zh;q=0.9","Cache-Control": "no-cache","Pragma": "no-cache","Proxy-Connection": "keep-alive","Referer": "http://xxx.xxx.xxx.xxx:81/n_score/", # 此处应与查询的IP和端口一致"Host": "xxx.xxx.xxx.xxx:81", # 此处应与查询的IP和端口一致"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
}
cookies = {"JSESSIONID": "FB32CDA83DF30554A9C01A2BE77260B6", # 实际使用时请替换"Hm_lvt_9b3b578b0b797c6004bfd68445de9e88": "1687654663" # 时间戳可以不要
}base_url = "https://xxx.xxx.xxx.xxx/cx/" # 查询入口主页
idNumber = "your_id_number" # 替换为实际身份证号
ticketNumber = "your_ticket_number" # 替换为实际准考证号
base_query_url_template = 'http://{}/n_score/rest/api/queryscore/snquery' # 查询接口模板
base_captcha_url_template = 'http://{}/n_score/Kaptcha.do' # 生成验证码接口模板# 获取查询接口列表
href_list = get_query_endpoints(session, base_url)
url_cycle = itertools.cycle(href_list) # 将查询接口用于循环迭代# 使用 schedule 模块每分钟执行一次 job
schedule.every(1).minutes.do(job)while not terminate:schedule.run_pending()time.sleep(1)print("程序结束")
几点说明:
1、在Server酱中传送json或text
# 假定得到的结果为字典
text = {"querytime": "查询时间:2022-09-22 12:46:47", "totalScore": " 433"}
# 将结果转为json
json_text = json.dumps(text, ensure_ascii=False)
data = {'title': '查询结果通知','desp': json_text
}
headers = {'Content-Type': 'application/json'} # 在头中设置Content-Type 为 json
response = requests.post("https://sctapi.ftqq.com/你自己的key.send?title={}", data=data, headers=headers)#############################################################################################
# 如果结果为table, 可将table转为列表,再转成文格传送
# 提取表格数据
table_data = []
for table in soup.find_all('table'):for row in table.find_all('tr'):cols = row.find_all(['td'])cols = [ele.text.strip() for ele in cols]table_data.append(cols)# 将列表中的元素都转换为字符串类型
str_list = [str(item) for item in table_data]
# 使用 join() 方法将列表转换为文本
text = ', '.join(str_list)data = {'title': '查询结果通知','desp': text
}
response = requests.post("https://sctapi.ftqq.com/你自己的key.send?title={}", data=data)
2、为了确保在查询分数网页和获取验证码时使用同一个会话,我们需要确保所有与网络交互的请求都通过同一个requests.Session。
3、可以将程序部署到阿里云使用FC功能 ,在高考查分前一天触发,让其自动运行直到查询到结果。
此程序是基于我去年成功运行的版本进行修改的。目前,由于今年的查分接口尚未发布,我只能使用去年的接口列表进行开发。因此,当下的接口无法Ping通。基于此限制,我在理论上完成了整个程序,但尚未进行实际测试。
希望以后高考分数,家长和考生第一时间知晓,自动推送。家长无需费心,考生无需烦恼,无需查询,消息早已送达。此时我无需多言,只愿学子一举夺魁,金榜题名。
相关文章:
高考分数查询结果自动推送至微信(卷II)
祝各位端午节安康!只要心中无结,每天都是节,开心最重要! 在上一篇文章高考分数查询结果自动推送至微信(卷Ⅰ)-CSDN博客中谈了思路,今天具体实现。文中将敏感信息已做处理,读者根据自…...
python类动态属性,以属性方式访问字典
动态属性能够用来描述变化的类,在实际应用中容易遇到用到。 import logging class Sample:def __init__(self):self.timeNoneself.sampleidNoneself.massNoneself.beizhu""self.num0self.items{}#字典属性def __getattribute__(self, attr): #注意&#…...
招聘在家抄书员?小心是骗局!!!
在家抄书员的骗局是一种常见的网络诈骗手段,旨在利用人们想要在家轻松赚钱的心理。这种骗局通常会以招聘兼职抄写员的形式出现,声称只需在家中抄写书籍即可赚取可观的收入。然而,实际上这背后隐藏着诸多陷阱和虚假承诺。 首先,这些…...
Pytorch学习11_神经网络-卷积层
1.创建神经网络实例 import torch import torchvision from torch import nn from torch.nn import Conv2d from torch.utils.data import DataLoaderdatasettorchvision.datasets.CIFAR10("../dataset_cov2d",trainFalse,transformtorchvision.transforms.ToTensor(…...
Qt实现程序单实例运行(只能运行1个进程)及QSharedMemory用法
1. 问题提出 在开发时,经常遇到这样的需求或场景:程序只能被启动一次,不能启动多次,启动多次会导致混乱,如:可执行程序用到文件指针、串口句柄等。试想如果存在多个同一个文件的句柄或同一个串口的句柄&…...
HTTP协议分析实验:通过一次下载任务抓包分析
HTTP协议分析 问:HTTP是干啥用的? 最简单通俗的解释:HTTP 是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。 在Internet上的Web服务器上存放的都是超文本信息,客户机需要通过HTTP协议传输所要访问的超文本信息。 一、…...
http网络服务器
wwwroot(目录)/index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>比特就业课</title>…...
使用C++结合OpenCV进行图像处理与分类
⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三…...
探索 Noisee AI 的奇妙世界与变现之旅
日赚800,利用淘宝/闲鱼进行AI音乐售卖实操 如何让AI生成自己喜欢的歌曲-AI音乐创作的正确方式 抖音主播/电商人员有福了,利用Suno创作产品宣传,让产品动起来-小米Su7 用sunoAI写粤语歌的方法,博主已经亲自实践可行 五音不全也…...
【SCSS】use的详细使用规则
目录 use加载成员选择命名空间私有成员配置使用 Mixin重新赋值变量 use 从其他 Sass 样式表中加载 mixins、函数和变量,并将来自多个样式表的 CSS 组合在一起。use加载的样式表被称为“模块”。 加载成员 // src/_corners.scss $radius: 3px;mixin rounded {bord…...
数据结构(C):二叉树前中后序和层序详解及代码实现及深度刨析
目录 🌞0.前言 🚈1.二叉树链式结构的代码是实现 🚈2.二叉树的遍历及代码实现和深度刨析代码 🚝2.1前序遍历 ✈️2.1.1前序遍历的理解 ✈️2.1.2前序代码的实现 ✈️2.1.3前序代码的深度解剖 🚝2.2中序遍历 ✈…...
Win11可以安装AutoCAD2007
1、在win11中,安装AutoCAD2007,需要先安装NET组件。否则会提示缺少".net文件" 打开“控制面板”,点击“程序”,点击“程序和功能”,点击“启用或关闭Windows功能”,勾选“.NET FrameWork 3.5”&a…...
C#操作MySQL从入门到精通(14)——汇总数据
前言 我们有时候需要对数据库查询的值进行一些处理,比如求平均值等操作,本文就是详细讲解这些用法,本文测试使用的数据库数据如下: 1、求平均值 求所有student_age 列的平均值 string sql = string.Empty; if (radioButton_AVG.Checked) {sql = “select AVG( student_…...
【设计模式深度剖析】【2】【行为型】【命令模式】| 以打开文件按钮、宏命令、图形移动与撤销为例加深理解
👈️上一篇:模板方法模式 | 下一篇:职责链模式👉️ 设计模式-专栏👈️ 文章目录 命令模式定义英文原话直译如何理解呢? 四个角色1. Command(命令接口)2. ConcreteCommand(具体命令类&…...
【随手记】maplotlib.use函数设置图像的呈现方式
matplotlib.use() 函数用于设置 matplotlib 的后端,这会影响图形的呈现方式。不同的后端适用于不同的环境和需求。下面列出一些常用的后端及其描述: 常见后端参数 Agg: 参数:agg描述:基于Anti-Grain Geometry的后端,适…...
LLVM Cpu0 新后端 系列课程总结
想好好熟悉一下llvm开发一个新后端都要干什么,于是参考了老师的系列文章: LLVM 后端实践笔记 代码在这里(还没来得及准备,先用网盘暂存一下): 链接: https://pan.baidu.com/s/1yLAtXs9XwtyEzYSlDCSlqw?…...
【云原生】Kubernetes----RBAC用户资源权限
目录 引言 一、Kubernetes安全机制概述 二、认证机制 (一)认证方式 1.HTTPS证书认证 1.1 证书颁发 1.2 config文件 1.3 认证类型 1.4 Service Account 1.4.1 作用 1.4.2 包含内容 1.4.3 与Secret的关系 2.Bearer Tokens 3.基本认证 三、鉴…...
ORA-01652 表空间不够解决方案
前章:出现表空间不足不要手动强制删除对应数据文件存储目录下的DBF文件,需要用SQL语句进行数据文件的DROP,否则会导致ORA-01033报错,因为我没有开启数据库的归档所以不能通过RECOVER的形式找回数据文件最后只能重装本地ORACLE。 …...
亚马逊 AWS 视频转码功能、AWS Elemental MediaConvert 中创建和管理转码作业
上传的视频需要转码成不同的编码, 可以直接在 AWS Elemental MediaConvert 中创建和管理转码作业 AWS Elemental MediaConvert 中创建和管理转码作业 /*** 视频转码* return bool* author wzb* data 2024/5/30*/function videoTranscode(&$data){$fileId $data[id] ?? …...
RocketMQ可视化界面安装
RocketMQ可视化界面安装 **起因:**访问rocketmq-externals项目的git地址,下载了源码,在目录中并没有找到rocketmq-console文件夹。 git下面文档提示rocketMQ的仪表板转移到了新的项目中,点击仪表板到新项目地址; 下载…...
【ffmpeg】本地格式转换 mp4转wav||裁剪mp4
个人感受:太爽了!!!(可能用惯了转换网站和无良的转换软件) ———— 使用FFmpeg把mp4文件转换为WAV文件 - 简书 (jianshu.com) FFMPEG 视频分割和合并 - 简书 (jianshu.com) ———— 示例 ffmpeg -i …...
基于Django+MySQL的智慧校园系统
此项目基于Django MySQL HTML CSS JS jQuery bootstrap实现的功能有 学生管理部门管理代办清单管理校园论坛校园医疗服务校园看点校园生活助手常用功能入口 1. 一些注意点 1. 页面body会自动有一些边界距,处理方法: <head><style>b…...
Linux基础指令(一)
前言 Linux基础指令主要学习:对目录、文件、压缩包、匹配查找,权限等操作 第一次接触ubuntu需要知道的基本知识 sudo passwd root 先给root用户设置密码 su root 切换到root用户 su zhangsan …...
三极管十大品牌
三极管十大品牌-三极管品牌-晶体三极管哪个品牌好-Maigoo品牌榜...
需求记录(共享元素)
MainActivity1 列表展示,使用共享元素完成页面间的切换 package com.example.animactivity;import android.annotation.SuppressLint; import android.app.ActivityOptions; import android.content.Intent; import android.os.Build; import android.os.Bundle; i…...
.Net 使用 MongoDB
安装nuget包 MongoDB.Driver 简单代码 using MongoDB.Bson; using MongoDB.Driver; using System.Buffers; using System.Collections.Concurrent; using System.Diagnostics;namespace ConsoleApp4 {internal class Program{static void Main(string[] args){var client = ne…...
【TensorFlow深度学习】值函数估计:蒙特卡洛方法与TD学习
值函数估计:蒙特卡洛方法与TD学习 值函数估计:蒙特卡洛方法与TD学习的深度探索蒙特卡洛方法时序差分学习(TD)Python代码示例结论 值函数估计:蒙特卡洛方法与TD学习的深度探索 在强化学习的奇妙世界里,值函数估计扮演着至关重要的…...
成功解决ModuleNotFoundError: No module named ‘cv2’
成功解决ModuleNotFoundError: No module named ‘cv2’ 🌈 欢迎莅临我的个人主页👈这里是我深耕Python编程、机器学习和自然语言处理(NLP)领域,并乐于分享知识与经验的小天地!🎇 🎓…...
中国蚁剑 安装教程 2024年5月
2024/5/11 中国蚁剑 安装教程 一、下载中国蚁剑的加载器和核心源码(两个都要用到) github官方下载地址:https://github.com/AntSwordProject/ 参考文档:antSword/README_CN.md at master AntSwordProject/antSword GitHub 核…...
Golang-分离式加载器(传参)AES加密
目录 enc.go 生成: dec.go --执行dec.go...--上线 cs生成个c语言的shellcode. enc.go go run .\enc.go shellcode 生成: --key为公钥. --code为AES加密后的数据, ----此脚本每次运行key和code都会变化. package mainimport ("bytes""crypto/aes"&…...
wordpress用户注册打文章/建网站需要多少钱和什么条件
网络策略介绍 默认情况下,Kubernetes 集群网络没任何网络限制,Pod 可以与任何其他 Pod 通信,在某些场景下就需要进行网络控制,减少网络攻击面,提高安全性,这就会用到网络策略。 网络策略(Netwo…...
在网站上做教育直播平台多少钱/淘特app推广代理
另外%f标识的数会被当成double读取,即取出8个字节读取。...
wordpress 蜘蛛插件/长沙seo顾问
00.如果你期望学习一种对所有项目都适用的方法,那只是一种远离现实的妄想。成为一位有效的项目经理将会是一项挑战你哥哥方面创造性的经历,所以你讲从基本原理开始学习。 01.《PMBOK指南》描述的是过程而非方法论。你或者你的管理,应当定义你…...
电子商务 网站建设/东莞网络公司排行榜
集群要求 1.下载安装MongoDB 官网下载压缩包 https://www.mongodb.com/download-center?jmpnav#community 或者 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.1.3.tgz解压缩 tar -xzvf mongodb-linux-x86_64-4.1.3.tgz mv mongodb-linux-x86_64-4.1.3…...
台州经济开发区管委会建设网站/检测网站是否安全
public class Clerk {private int product0;//产品默认0;//生产者生成出来的产品交给店员public synchronized void addProduct(){if(this.product>20){try {wait();//产品已满,请稍等在生产} catch (InterruptedException e) {// TODO 自动生成的 catch 块e.pri…...
苏宁网站建设/如何搭建网站平台
推荐成功入职:您的悬赏金约为3000-20000元不等,视岗位年薪简历接收邮箱:hrchinese-hr.com推荐者发邮件:请备注联系方式,方便我们后续给您支付悬赏金。公司对接微信:greatway66高级Java架构师(深圳/厦门)岗位…...