多群管理/自动检测Q群人数 切换入群链接 一个URL就能搞定!附思路/PHP代码

杂谈

其实很早的时候我们就给大家分享过通过自己域名跳转Q群的教程

其实代码非常简单,就是用的meta标签进行跳转

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <title>正在跳转</title>
    <link rel="shortcut icon" href="https://www.iculture.cc/icon/logo.ico" type="image/x-icon">
    <meta http-equiv="refresh" content="0;url=https://jq.qq.com/?_wv=1027&k=YRiWzf8c">
</head>
</html>

跳转群链接要提前设置好

<meta http-equiv="refresh" content="0;url=https://jq.qq.com/?_wv=1027&k=YRiWzf8c">

但是人总是懒的,况且很多热心网友表示自己运营的群太多了,定期去修改指定某个群的URL感觉好累了!

图片[1]-多群管理/自动检测Q群人数 切换入群链接 一个URL就能搞定!附思路/PHP代码-FancyPig's blog

接下来就有了本期的教程,我们现在已经实现了,自动检测群人数,如果满了自动切换下一个群链接

https://www.iculture.cc/qun

实现思路

首先我们要思考下面的问题

  • 如何判断Q群人满了?
  • 如何生成Q群链接?

QQ群人有没有满?如何通过接口判断?

这两个问题通过下面这个网站都可以解决

https://qun.qq.com/

我们进入群管理页面,我们发现在点击成员管理

图片[2]-多群管理/自动检测Q群人数 切换入群链接 一个URL就能搞定!附思路/PHP代码-FancyPig's blog

请求了相关接口

图片[3]-多群管理/自动检测Q群人数 切换入群链接 一个URL就能搞定!附思路/PHP代码-FancyPig's blog
请求接口URLhttps://qun.qq.com/cgi-bin/qun_mgr/search_group_members
请求方式POST
请求头由于过长,这里隐藏,但是不可缺少(因为里面cookie需要验证QQ账户)
请求载荷gc=208911329&st=0&end=20&sort=0&bkn=1737682914
请求结构

我们可以发现gc=后面的208911329是我们的群号

同时我们获得下面的响应体

{"ec":0,"errcode":0,"em":"","cache":0,"adm_num":2,"levelname":null,"mems":[{"uin":858887520,"role":0,"g":0,"join_time":1645658214,"last_speak_time":1665478404,"lv":{"point":0,"level":1},"card":"\u5173\u6ce8\u5fae\u4fe1\u516c\u4f17\u53f7","tags":"-1","flag":0,"nick":"\u732a\u732a\u4fa0","qage":8,"rm":0},{"uin":66882930,"role":1,"g":-1,"join_time":1645658214,"last_speak_time":1660986989,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u2062\u2062","qage":21,"rm":1},{"uin":210001314,"role":1,"g":1,"join_time":1645659409,"last_speak_time":1659952327,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u732a\u5934","qage":4,"rm":1},{"uin":2662686939,"role":2,"g":-1,"join_time":1645710394,"last_speak_time":1645710394,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"1uh5an","qage":8,"rm":1},{"uin":1984326315,"role":2,"g":0,"join_time":1645711613,"last_speak_time":1645711613,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u4ee3\u7801\u4e0e\u8bd7","qage":10,"rm":1},{"uin":3414387632,"role":2,"g":0,"join_time":1645712299,"last_speak_time":1645712299,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"CBG","qage":5,"rm":1},{"uin":2683113838,"role":2,"g":-1,"join_time":1645713221,"last_speak_time":1645713221,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"404 RUL","qage":3,"rm":1},{"uin":2573925869,"role":2,"g":-1,"join_time":1645713484,"last_speak_time":1645713484,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u2741\u2741","qage":0,"rm":1},{"uin":3058678420,"role":2,"g":-1,"join_time":1645715176,"last_speak_time":1645715176,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u62d2\u7edd\u9171\uff08\u6697\u533a\u7b2c\u4e00\u6148\u5584\u5bb6\uff09","qage":0,"rm":1},{"uin":2784762049,"role":2,"g":0,"join_time":1645715272,"last_speak_time":1645715303,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u5b59\u67d0\u4eba","qage":3,"rm":1},{"uin":2918364378,"role":2,"g":-1,"join_time":1645715489,"last_speak_time":1645715617,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"Bullshit love","qage":9,"rm":1},{"uin":1124916437,"role":2,"g":-1,"join_time":1645716717,"last_speak_time":1645716717,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"ANON","qage":13,"rm":1},{"uin":1280932578,"role":2,"g":0,"join_time":1645717041,"last_speak_time":1645717041,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u683c\u6805\u59b2\u449c","qage":7,"rm":1},{"uin":1105613747,"role":2,"g":1,"join_time":1645717484,"last_speak_time":1645717484,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u6b4c\u59ec","qage":2,"rm":1},{"uin":2922473703,"role":2,"g":1,"join_time":1645718129,"last_speak_time":1645718129,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u6e21\u6625\u98ce","qage":7,"rm":1},{"uin":1319156460,"role":2,"g":-1,"join_time":1645719747,"last_speak_time":1645719747,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u6c5f\u90ce\u624d\u5c3d","qage":11,"rm":1},{"uin":775233780,"role":2,"g":0,"join_time":1645720368,"last_speak_time":1645724301,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"X.","qage":14,"rm":1},{"uin":2834263401,"role":2,"g":-1,"join_time":1645723700,"last_speak_time":1645723725,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"\u574f\u60c5\u7eea","qage":7,"rm":1},{"uin":598106895,"role":2,"g":1,"join_time":1645725723,"last_speak_time":1645725723,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"v\uff1a2278689375","qage":13,"rm":1},{"uin":3030974610,"role":2,"g":-1,"join_time":1645726159,"last_speak_time":1645726159,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"Jay.","qage":3,"rm":1},{"uin":746916596,"role":2,"g":1,"join_time":1645729649,"last_speak_time":1645729649,"lv":{"point":0,"level":1},"card":"","tags":"-1","flag":0,"nick":"Mikoto","qage":8,"rm":1}],"count":1970,"svr_time":1665557128,"max_count":2000,"search_count":1970,"extmode":0}

我们发现里面可以获取部分群员的信息,比方说QQ号和加群的时间,但是这些都不重要,我们只关心群有没有满这个问题?可以看到其中有两个字段在结尾部分

"count":1970,"svr_time":1665557128,"max_count":2000,"search_count":1970,"extmode":0}
  • max_count:群最高人数
  • count:群现有人数

那我们是否可以在简化一下上面的步骤,群成员的信息我们不要呢?我们尝试改变请求

请求接口URLhttps://qun.qq.com/cgi-bin/qun_mgr/search_group_members
请求方式POST
请求头由于过长,这里隐藏,但是不可缺少(因为里面cookie需要验证QQ账户)
请求载荷gc=208911329&bkn=1737682914
请求结构

这样请求之后我们发现,响应结果就变得非常简单了,理论上这么做可以减少占用的服务资源,会提升获取的速度

{"ec":0,"errcode":0,"em":"","cache":0,"adm_num":2,"levelname":null,"mems":[{"uin":858887520,"role":0,"g":0,"join_time":1645658214,"last_speak_time":1665478404,"lv":{"point":0,"level":1},"card":"\u5173\u6ce8\u5fae\u4fe1\u516c\u4f17\u53f7","tags":"-1","flag":0,"nick":"\u732a\u732a\u4fa0","qage":8,"rm":0}],"count":1970,"svr_time":1665557744,"max_count":2000,"search_count":1970,"extmode":0}

既然这种方式是有效的,那我们就可以立即开整了,浏览器里有一个很强大的功能

在我们找到的接口中,复制>以cURL(bash)格式复制

图片[4]-多群管理/自动检测Q群人数 切换入群链接 一个URL就能搞定!附思路/PHP代码-FancyPig's blog

之后,我们为大家准备了一个CURL转PHP代码的在线网站

图片[5]-多群管理/自动检测Q群人数 切换入群链接 一个URL就能搞定!附思路/PHP代码-FancyPig's blog

之后我们可以快速获取到转换后的php代码

// Generated by FancyPig Tool: https://www.iculture.cc/demo/curl_to_php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://qun.qq.com/cgi-bin/qun_mgr/search_group_members');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "gc=208911329&st=0&end=20&sort=0&bkn=1737682914");
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');

$headers = array();
$headers[] = 'Authority: qun.qq.com';
$headers[] = 'Accept: application/json, text/javascript, */*; q=0.01';
$headers[] = 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8';
$headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8';
$headers[] = 'Cookie: 填你自己的Cookie';
$headers[] = 'Origin: https://qun.qq.com';
$headers[] = 'Referer: https://qun.qq.com/member.html';
$headers[] = 'Sec-Ch-Ua: \"Chromium\";v=\"106\", \"Google Chrome\";v=\"106\", \"Not;A=Brand\";v=\"99\"';
$headers[] = 'Sec-Ch-Ua-Mobile: ?0';
$headers[] = 'Sec-Ch-Ua-Platform: \"Windows\"';
$headers[] = 'Sec-Fetch-Dest: empty';
$headers[] = 'Sec-Fetch-Mode: cors';
$headers[] = 'Sec-Fetch-Site: same-origin';
$headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36';
$headers[] = 'X-Requested-With: XMLHttpRequest';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

通过上面的代码是可以请求并获取到结果的,这时,我们可以进一步进行操作,比方说,我们先将获取的结果$result进行JSON格式化,并打印

$result = json_decode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
print_r($result);

打印结果为

Array ( [ec] => 0 [errcode] => 0 [em] => [cache] => 0 [adm_num] => 2 [levelname] => [mems] => Array ( [0] => Array ( [uin] => 858887520 [role] => 0 [g] => 0 [join_time] => 1645658214 [last_speak_time] => 1665478404 [lv] => Array ( [point] => 0 [level] => 1 ) [card] => 关注微信公众号 [tags] => -1 [flag] => 0 [nick] => 猪猪侠 [qage] => 8 [rm] => 0 ) ) [count] => 1970 [svr_time] => 1665558193 [max_count] => 2000 [search_count] => 1970 [extmode] => 0 )

然后我们需要去取刚才说的countmax_count的值,并打印

$member_total = $result['max_count'];
$member_now = $result['count'];

print($member_total);
print("\n");
print($member_now);

这里我们可以看到已经获取到了

2000 1970

那既然已经拿到值了,你还可以做更多的事情,比方说判断群人数是不是满了?

if ($member_now < $member_total){
    print("群没有满");
    print("现有人数:$member_now");
}else {
    $msg="群人满了";
}

当然,你还可以把刚才的请求写成一个函数,这样可以去接收网页里的传参,这就是我们常说的接口

需要强调的是,目前这种方式都需要使用您自己QQ的cookie,并不能通用!

也就是说不能用我QQ的cookie获取你的QQ群人数情况,因为我不在群里,在群成员官网也是访问不到的!

我们对上述接口进行测试

https://www.iculture.cc/qun/qun.php?qun=

比方说,我们查询一下208911329群有没有满?

https://www.iculture.cc/qun/qun.php?qun=208911329

可以看到返回结果

{"Qun_number":"208911329","member_total":2000,"member_now":1970,"is_max":false,"msg":"群没有满","result":200}

这样第一步就完成了!我们解决了群人数有没有满的判断问题

如何生成Q群链接?

这时,我们看到下面的链接

https://qun.qq.com/join.html

有一个加群组件,我们继续按照之前的方式对接口进行分析

图片[6]-多群管理/自动检测Q群人数 切换入群链接 一个URL就能搞定!附思路/PHP代码-FancyPig's blog
请求接口URLhttps://qun.qq.com/proxy/domain/admin.qun.qq.com/cgi-bin/qun_admin/get_join_k
请求方式POST
请求头由于过长,这里隐藏,但是不可缺少(因为里面cookie需要验证QQ账户)
请求载荷gc=387568&bkn=1737682914
请求结构

这里相当于生成的是QQ群387568的加群链接,我们观察下返回结果

{"ec":0,"errcode":0,"em":"","k":"ZJKca347RkycBiJ2m1Pfg1_S330Jlenv","auth_key":"+kf6B\/DacbW3FkGLTZpwfrl5bcRFY19ObX0FT\/iEJKfCDgCsXUrOeVdI\/zuZ0bQ5"}

以及界面上给我们的链接代码

https://qm.qq.com/cgi-bin/qm/qr?k=ZJKca347RkycBiJ2m1Pfg1_S330Jlenv&jump_from=webapi&authKey=+kf6B/DacbW3FkGLTZpwfrl5bcRFY19ObX0FT/iEJKfCDgCsXUrOeVdI/zuZ0bQ5

这时,我们可以清晰地看到结构,生成的K值生成的authKey二者是变量,每次都在更换

https://qm.qq.com/cgi-bin/qm/qr?k=生成的K值&jump_from=webapi&authKey=生成的authKey

因此,我们可以继续按照刚才的方式,复制>以cURL(bash)格式复制

图片[7]-多群管理/自动检测Q群人数 切换入群链接 一个URL就能搞定!附思路/PHP代码-FancyPig's blog

然后使用我们的工具转PHP代码

// Generated by FancyPig Tool: https://www.iculture.cc/demo/curl_to_php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://qun.qq.com/proxy/domain/admin.qun.qq.com/cgi-bin/qun_admin/get_join_k');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "gc=387568&bkn=1737682914");
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');

$headers = array();
$headers[] = 'Authority: qun.qq.com';
$headers[] = 'Accept: */*';
$headers[] = 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8';
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
$headers[] = 'Cookie: 填你自己的Cookie值';
$headers[] = 'Origin: https://qun.qq.com';
$headers[] = 'Referer: https://qun.qq.com/proxy.html?callback=1&id=1';
$headers[] = 'Sec-Ch-Ua: \"Chromium\";v=\"106\", \"Google Chrome\";v=\"106\", \"Not;A=Brand\";v=\"99\"';
$headers[] = 'Sec-Ch-Ua-Mobile: ?0';
$headers[] = 'Sec-Ch-Ua-Platform: \"Windows\"';
$headers[] = 'Sec-Fetch-Dest: empty';
$headers[] = 'Sec-Fetch-Mode: cors';
$headers[] = 'Sec-Fetch-Site: same-origin';
$headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

之后,我们可以继续对结果进行分析,这里我们不再赘述,直接分享写成接口的代码

需要强调的是,目前这种方式都需要使用您自己QQ的cookie,并不能通用!

也就是说不能用我QQ的cookie获取你的QQ群人数情况,因为我不在群里,在群成员官网也是访问不到的

我们对上述接口进行测试

https://www.iculture.cc/qun/join.php?qun=

比方说我们想加入387568这个Q群,则请求下面的URL

https://www.iculture.cc/qun/join.php?qun=387568

可以看到响应结果,里面已经为我们自动生成了k和authKey,我这里还定义了一个join_link的变量,这个就是我们的加群链接,已经拼接好了

{ "Qun_number": "387568", "k": "cxVpnDNAF7aHLuRd0SMBvAGni0-gyhGC", "auth_key": "9m4NvMN4EXX1CRg7PfYQFLnZy40PCYh39x/SsixqheD+2TDvIJg1y39eSCFaz9y+", "join_link": "https://qm.qq.com/cgi-bin/qm/qr?k=cxVpnDNAF7aHLuRd0SMBvAGni0-gyhGC&jump_from=webapi&auth_key=9m4NvMN4EXX1CRg7PfYQFLnZy40PCYh39x/SsixqheD+2TDvIJg1y39eSCFaz9y+", "msg": "生成成功", "result": 200 }

自动切换Q群链接的实现

既然我们已经完成了上面的两步,我们现在已经可以判断Q群人数是否满了?Q群链接自动生成也可以做,那下面就是水到渠成的事情了,首先我们把我现有的QQ群号列出来,写在一个数组里

$qun=[387568,832028452,760887453,177746268,195757763,285522610,939083268,225905977,532539604,887485075,984233903,208911329,958383847,724938146,690168627,303510405];

然后我们去遍历每个元素,比方说,我们想获取第一个QQ群387568,则是下面的变量(代码规范:从0开始哦

$qun[0]

之后写个循环呗,这里有两个函数

  • curl_get 这个函数用来传群人数是否满了的结果
  • curl_join 这个函数用来传加群链接的跳转
for ($i=0; $i<=15; $i++)
{
    if (curl_get($qun[$i]) == FALSE)
    {
        curl_join($qun[$i]);
        break;
    }else{
        print("群人满了");
        continue;
    }
}

curl_get函数

我们相当于在请求自己写好的接口

https://www.iculture.cc/qun/qun.php?qun=

我们只关注is_max返回是True还是False,是True代表人满了,那就跳下一个群……是False代表人没满,还可以加入,就生成链接就好了!

核心代码

function curl_get($qun){
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://www.iculture.cc/qun/qun.php?qun=$qun");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
//print($result);
$result = json_decode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
// print_r($result);
$is_max = $result['is_max'];
return $is_max;
}

curl_join函数

用来自动跳转Q群,使用最简单的php代码,跳转我们获取到的$join_link地址

header("Location:$join_link");

核心代码

function curl_join($qun){
    $ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://www.iculture.cc/qun/join.php?qun=$qun");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
$result = json_decode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
// print_r($result);
$join_link = $result['join_link'];
header("Location:$join_link");
}

完整代码

<?php
$qun=[387568,832028452,760887453,177746268,195757763,285522610,939083268,225905977,532539604,887485075,984233903,208911329,958383847,724938146,690168627,303510405];
for ($i=0; $i<=15; $i++)
{
    if (curl_get($qun[$i]) == FALSE)
    {
        curl_join($qun[$i]);
        break;
    }else{
        print("群人满了");
        continue;
    }
}

function curl_get($qun){
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://www.iculture.cc/qun/qun.php?qun=$qun");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
//print($result);
$result = json_decode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
// print_r($result);
$is_max = $result['is_max'];
return $is_max;
}

function curl_join($qun){
    $ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://www.iculture.cc/qun/join.php?qun=$qun");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
$result = json_decode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
// print_r($result);
$join_link = $result['join_link'];
header("Location:$join_link");
}



?>

效果展示

我们最终将完整代码放到index.php就可以咯!

https://www.iculture.cc/qun
© 版权声明
THE END
喜欢就支持一下吧
点赞16赞赏 分享
评论 共30条

请登录后发表评论