校园招新之获取进QQ群但未报名人员

校园的社团、实验室招新一般由是校领导会发一个QQ通知,让各个班的同学们进一个招新群。 群里面会有负责人提示大家报名,但是群成员不总是都会报名,我们需要的就是,找到那些,已经进群,但是没有报名的同学,然后私聊提醒一下。

大体思路:获取QQ群成员列表,获取已经报名的人员(从问卷星导出,使用go读取execl),根据两者(我们使用QQ群昵称 “计科203张三” 和 execl中的班级+姓名作为判断标准)即可求出我们想要的差集合并集。  

获取QQ群成员列表

参考文章:js解密之QQ的bkn值,获取QQ群成员信息,获取QQ好友列表信息-腾讯云开发者社区-腾讯云

 进入网站:https://qun.qq.com/member.html 登录,选择群,打开网络请求

解析参数:

  • gc,应该是群id
  • st: 开始下标 
  • end :结束下标
  • sort:不知道
  • bkn:加密用的应该是

解析response

  •  adm_num :管理员数量,不带群主
  • count: 群成员总数
  • mems : 群成员列表
  • mems.role : 0是群主,1是管理员,2是群成员
  • card: 群昵称

nick:QQ昵称

 使用网络抓包即可,导入apifox即可

 具体代码

package mainimport ("encoding/json""fmt""github.com/360EntSecGroup-Skylar/excelize""io/ioutil""net/http""strings""time"
)type QQUser struct {Uin           int `json:"uin"`Role          int `json:"role"`G             int `json:"g"`JoinTime      int `json:"join_time"`LastSpeakTime int `json:"last_speak_time"`Lv            struct {Point int `json:"point"`Level int `json:"level"`} `json:"lv"`Card string `json:"card"`Tags string `json:"tags"`Flag int    `json:"flag"`Nick string `json:"nick"`Qage int    `json:"qage"`Rm   int    `json:"rm"`
}
type JSONData struct {Ec          int         `json:"ec"`Errcode     int         `json:"errcode"`Em          string      `json:"em"`Cache       int         `json:"cache"`AdmNum      int         `json:"adm_num"`Levelname   interface{} `json:"levelname"`Mems        []QQUser    `json:"mems"`Count       int         `json:"count"`SvrTime     int         `json:"svr_time"`MaxCount    int         `json:"max_count"`SearchCount int         `json:"search_count"`Extmode     int         `json:"extmode"`
}
type WJXUser struct {Class stringName  string
}func ReadExcel(filename string) (RegisteredUserList []WJXUser, err error) {f, err := excelize.OpenFile(filename)if err != nil {return}sheets := f.GetSheetMap() //获取Execl表的工作表fmt.Println(sheets)sheet1 := sheets[1] //sheets是一个map,map[1]就是获取到第一个工作表fmt.Println("第一个工作表", sheet1)rows := f.GetRows(sheet1) //获取工作表的所有数据,数据存储在一个二维数组中,二维数组中的每一个一位数组就是一行数据fmt.Println(rows)RegisteredUserList = make([]WJXUser, 0)for i := 1; i < len(rows); i++ {name := strings.ReplaceAll(rows[i][6], " ", "")name = strings.ReplaceAll(name, "&nbsp;", "")class := strings.ReplaceAll(rows[i][9], " ", "")class = strings.ReplaceAll(class, "&nbsp;", "")class = strings.ReplaceAll(class, "班", "")RegisteredUser := WJXUser{Name: name, Class: class}RegisteredUserList = append(RegisteredUserList, RegisteredUser)}return RegisteredUserList, err
}
func main() {url := "https://qun.qq.com/cgi-bin/qun_mgr/search_group_members"method := "POST"client := &http.Client{}NotedUserList := make([]QQUser, 0)  // 已经进QQ群且已经备注人员 (已经剔除管理员)NoNoteUserList := make([]QQUser, 0) // 已经进QQ群但是未备注人员(已经剔除管理员)countMember := 0                    // 群成员总数量cycleIndex := 1                     // 刚开始让循环一轮,后面根据群成员总数来确定到底循环多少轮for i := 0; i < cycleIndex; i++ {st := i * 21end := st + 20if i != 0 && i == cycleIndex-1 { // For the fifth iteration, set the end to 86end = countMember}payload := strings.NewReader(fmt.Sprintf("gc=185335516&st=%d&end=%d&sort=0&bkn=336337277", st, end))req, err := http.NewRequest(method, url, payload)if err != nil {return}req.Header.Add("Accept", "application/json, text/javascript, */*; q=0.01")req.Header.Add("Accept-Language", "zh-CN,zh;q=0.9")req.Header.Add("Connection", "keep-alive")req.Header.Add("Origin", "https://qun.qq.com")req.Header.Add("Referer", "https://qun.qq.com/member.html")req.Header.Add("Sec-Fetch-Dest", "empty")req.Header.Add("Sec-Fetch-Mode", "cors")req.Header.Add("Sec-Fetch-Site", "same-origin")req.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36")req.Header.Add("X-Requested-With", "XMLHttpRequest")req.Header.Add("sec-ch-ua", "\"Google Chrome\";v=\"125\", \"Chromium\";v=\"125\", \"Not.A/Brand\";v=\"24\"")req.Header.Add("sec-ch-ua-mobile", "?0")req.Header.Add("sec-ch-ua-platform", "\"macOS\"")req.Header.Add("Cookie", "RK=Gdv1uMjH8g; ptcz=cc0188ccc671556dd56ea8ffb4ae59d282714e8e788826033f41c89d77b61b53; pgv_pvid=4845315920; tgw_l7_route=9d1d4698c4322116c7c255687ec1fe38; traceid=cfd4c1d7fb; uin=o3063360183; skey=@61HarNEbA; p_uin=o3063360183; pt4_token=e6WELkURyGZz0yu3RI3j1UwIQk5z9E7n9dUrbXmq4gE_; p_skey=GQ0pK0oDZsKCwOphrmWqZtFoCE5qsUVEqZfgDLHn7FU_")req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")req.Header.Add("Host", "qun.qq.com")res, err := client.Do(req)if err != nil {fmt.Println(err)return}defer res.Body.Close()body, err := ioutil.ReadAll(res.Body)if err != nil {fmt.Println(err)return}var r JSONDataerr = json.Unmarshal(body, &r)countMember = r.CountcycleIndex = countMember/21 + 1 // 每次查询是21人,不足21次的向上取整一下if err != nil {fmt.Println("Error unmarshalling response:", err)return}for j := 0; j < len(r.Mems); j++ {if r.Mems[j].Role == 2 {if r.Mems[j].Card == "" {NoNoteUserList = append(NoNoteUserList, r.Mems[j])} else {// 数据处理,让数据保持格式为 “计科221张三”r.Mems[j].Card = strings.ReplaceAll(r.Mems[j].Card, " ", "")r.Mems[j].Card = strings.ReplaceAll(r.Mems[j].Card, "&nbsp;", "")r.Mems[j].Card = strings.ReplaceAll(r.Mems[j].Card, "班", "")NotedUserList = append(NotedUserList, r.Mems[j])}}}time.Sleep(2 * time.Second)}registeredUserList, err := ReadExcel("/Users/yjppjy/Downloads/263778738_按序号_π-Team报名表_54_51.xlsx") // 已经报名人员if err != nil {return}// 根据 NoteUserList中的.Card字段 和 registeredUserList的 Class + Name 作为判断依据,以QQUser为基准,找出来 未进群但是已报名、已进群已报名、已进群未报名的人员// 将已报名人员存储在一个map中,以便快速查找registeredUserMap := make(map[string]WJXUser)for _, user := range registeredUserList {key := user.Class + user.NameregisteredUserMap[key] = user}// 查找已进群已报名、已进群未报名var notedAndRegistered []QQUservar notedAndNotRegistered []QQUserfor _, qqUser := range NotedUserList {key := qqUser.Cardif _, found := registeredUserMap[key]; found {notedAndRegistered = append(notedAndRegistered, qqUser)} else {notedAndNotRegistered = append(notedAndNotRegistered, qqUser)}}// 查找未进群但已报名var notInGroupButRegistered []WJXUserfor key, wjxUser := range registeredUserMap {found := falsefor _, qqUser := range NotedUserList {if qqUser.Card == key {found = truebreak}}if !found {notInGroupButRegistered = append(notInGroupButRegistered, wjxUser)}}// 输出结果//fmt.Println("已进群已报名:")//for _, user := range notedAndRegistered {//	fmt.Println(user.Card, user.Nick)//}fmt.Println("已进群未报名:")for _, user := range notedAndNotRegistered {fmt.Println(user.Card, user.Nick)}fmt.Println("未进群但已报名:")for _, user := range notInGroupButRegistered {fmt.Println(user.Class, user.Name)}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/841190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ELK 日志监控平台(一)- 快速搭建

文章目录 ELK 日志监控平台&#xff08;一&#xff09;- 快速搭建1.ELK 简介2.Elasticsearch安装部署3.Logstash安装部署4.Kibana安装部署5.日志收集DEMO5.1.创建SpringBoot应用依赖导入日志配置文件 logback.xml启动类目录结构启动项目 5.2.创建Logstash配置文件5.3.重新启动L…

当HR问你是否单身时,该怎么回答?

知识星球&#xff08;星球名&#xff1a;芯片制造与封测技术社区&#xff0c;星球号&#xff1a;63559049&#xff09;里的学员问&#xff1a;我是晶圆厂厂务工程师&#xff0c;最近在面试新工作&#xff0c;但是几乎每家HR都会问我同一个问题&#xff1a;你结婚没有&#xff1…

解密Spring Boot Starter与自动配置:探秘神奇的背后

starter可以理解为Spring Boot中的一站式集成启动器&#xff0c;包含了一系列可以集成到应用中的依赖项&#xff0c;可以快递集成spring组件及其框架&#xff0c;而不需要到处找示例代码。 一、为什么要用starter&#xff1f; 在springboot还没有出来之前&#xff0c;我们使用…

wps使用(解决毕业论文)

目录自动生成 页码自动生成 一部分使用I II III IV 格式&#xff0c;一部分使用1&#xff0c;2&#xff0c;3&#xff0c;4 格式 先设置全部文章为I II III IV 格式&#xff0c;然后再需要的地方再设置1&#xff0c;2&#xff0c;3&#xff0c;4 格式 一键设置中文、英文、数…

2024年全国大学生电工数学建模竞赛B题解析 | 数据处理 代码 论文分享

B 题&#xff1a;大学生平衡膳食食谱的优化设计及评价 1 数据预处理2 问题一2.1 问题1.12.1.1 评价体系的构建2.1.2 指标计算2.1.3 指标计算结果2.1.4 基于层次分析法的膳食营养评价模型2.1.5 评价模型的求解 2.2 问题1.22.2.1 食物与成分间拓扑关系的构建2.2.2 微调模型的建立…

【SpringBoot】整合百度文字识别

流程图 一、前期准备 1.1 打开百度智能云官网找到管理中心创建应用 全选文字识别 1.2 保存好AppId、API Key和Secret Key 1.3 找到通用场景文字识别&#xff0c;立即使用 1.4 根据自己需要&#xff0c;选择要开通的项目 二、代码编写 以通用文字识别&#xff08;高精度版&am…

蚁小二:又一款高效自媒体工具,免费用户可发5个账号

其实自媒体的群发工具有几个&#xff0c;除了前几天介绍的融媒宝还有蚁小二等。因为融媒宝免费用户只能添加5个账号&#xff0c;所以不够用的朋友可以再下载蚁小二使用&#xff0c;这样就有10个账号可以发布了&#xff1a; 蚁小二简介 蚁小二是由长沙草儿绽放科技有限公司自主…

mysql - 索引原理

mysql索引原理 文中的查询, 以该表结构为例 CREATE TABLE user (id int NOT NULL COMMENT id,name varchar(255) COLLATE utf8mb4_bin NOT NULL COMMENT 姓名,age int NOT NULL COMMENT 年龄,sex tinyint(1) NOT NULL COMMENT 性别,phone varchar(255) CHARACTER SET utf8mb4…

设计模式9——适配器模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 适配器模式&#xff08;Adapte…

酷开科技以内容为契机,酷开系统向消费者需求的深度挖掘迈进一步

酷开系统还拥有强大的内容资源和推荐算法&#xff0c;能够根据消费者的兴趣爱好为其提供个性化的推荐服务。无论是电影、电视剧、综艺节目&#xff0c;还是新闻、体育、娱乐资讯&#xff0c;酷开系统都能帮助大家快速找到感兴趣的内容&#xff0c;并且通过智能推荐算法不断优化…

(南京观海微电子)——TFT LCM的作用

VCOM介绍 VCOM是液晶分子偏转的参考电压 &#xff0c;要求要稳定&#xff0c;对液晶显示有直接影响&#xff0c;具体的屏不同的话 也是不同的。 电压的具体值是根据输入的数据以及Vcom电压大小来确定的&#xff0c;用来显示各种不同灰阶&#xff0c;也就是实现彩色显示GAMMA简…

YOLOv10详细解读 | 一文带你深入了解yolov10的创新点(附网络结构图 + 举例说明)

前言 Hello大家好&#xff0c;我是Snu77&#xff0c;继YOLOv9发布时间没有多久&#xff0c;YOLOv10就紧接着发布于2024.5.23号&#xff08;不得不感叹YOLO系列的发展速度&#xff0c;但要纠正大家的观点就是不是最新的就一定最好&#xff09;&#xff01; 本文给大家带来的是…

【CTF Web】CTFShow web6 Writeup(SQL注入+PHP+位运算)

web6 1 阿呆一口老血差点噎死自己&#xff0c;决定杠上了 解法 注意到&#xff1a; <!-- flag in id 1000 -->拦截很多种字符&#xff0c;连 select 也不给用了。 if(preg_match("/\|\"|or|\||\-|\\\|\/|\\*|\<|\>|\^|\!|x|hex|\(|\)|\|select/i"…

Textual for Mac:轻量级IRC客户端

在寻找一款高效、轻量级的IRC客户端时&#xff0c;Textual for Mac无疑是你的不二之选。它集成了众多现代技术&#xff0c;如本机IPv6、最新的IRCv3规范&#xff0c;以及客户端证书身份验证&#xff0c;让你的聊天体验更加顺畅和安全。 Textual for Mac v7.2.2免激活版下载 Tex…

【多线程开发 2】从代码到实战TransmittableThreadLocal

【多线程开发 2】从代码到实战TransmittableThreadLocal 本文将从以下几个点讲解TransmittableThreadLocal(为了方便写以下简称ttl)&#xff1a; 前身 是什么&#xff1f; 可以用来做什么&#xff1f; 源码原理 实战 前身 ThreadLocal 要了解ttl就要先了解Java自带的类…

C语言内存函数(与上篇字符函数及字符串函数一起食用效果更佳哦~)

顾名思义&#xff0c;内存函数就是针对内存块&#xff08;即一块内存&#xff09;来处理的。 因此本篇所讲的四种内存函数&#xff1a; memcpy&#xff08;内存拷贝&#xff09;memmove&#xff08;内存移动&#xff09;memset&#xff08;内存设置&#xff09;memcmp&#x…

5.Redis之常用数据结构单线程模型

围绕每个数据结构介绍相关命令当前版本的redis支持10个数据类型 Redis 底层在实现上述数据结构的时候,会在源码层面,针对上述实现进行特定的优化,来达到 节省时间/节省空间 效果,内部的具体实现的数据结构&#xff08;编码方式&#xff09;,还会有变数redis 承诺,现在我这有个 …

【Java EE】网络协议——HTTP协议

目录 1.HTTP 1.1HTTP是什么 1.2理解“应用层协议” 1.3理解HTTP协议的工作过程 2.HTTP协议格式 2.1抓包工具的使用 2.2抓包工具的原理 2.3抓包结果 3.协议格式总结 1.HTTP 1.1HTTP是什么 HTTP&#xff08;全称为“超文本传输协议”&#xff09;是一种应用非常广泛的应…

如何利用GitHubAction来发布自己的Python软件包

我们开发的python软件包如果想发布到网上&#xff0c;可以让其他人通过pip install下载&#xff0c;一般是把软件包发布到PYPI平台。 PYPI准备 我们要现在pypi注册登录一下 文件组织架构 一般的python软件包的文件组织架构为包名文件夹__init__.py程序&#xff0c;包文件夹的…

Django与前端框架协作开发实战:高效构建现代Web应用

title: Django与前端框架协作开发实战&#xff1a;高效构建现代Web应用 date: 2024/5/22 20:07:47 updated: 2024/5/22 20:07:47 categories: 后端开发 tags: DjangoREST前端框架SSR渲染SPA路由SEO优化组件库集成状态管理 第1章&#xff1a;简介 1.1 Django简介 Django是一…