一个菜鸡JAVA后端的博客~

Discuz模拟签到

由于大多论坛都是使用的Discuz程序,所以打算写一个签到的程序用于各个论坛的签到。本文模拟签到的论坛使用的是【DSU】每日签到。即签到页面是:https://域名/plugin.php?id=dsu_paulsign:sign的网站本文才对你有帮助。

抓包

首先先打开要签到的网站,本文随便找了个网站来进行测试。签到页面如下。

考虑到这个插件签到成功后会进行刷新,然后上图所示的内容就不显示了,这样就要等一天以后才能重新抓包了。所以先打开抓包工具。先错误的请求一次,即啥都不选直接签到。
顺便一提:这个地方是个form表单,可以直接查看源码来获取参数以及请求链接。但是为了省事,就直接抓包了。


发送请求后,打开请求的内容,查看请求头可以看到以下内容。

这些就是所有的请求参数了。

  • id
  • operation
  • infloat
  • inajax
  • formhash
  • qdxq
  • qdmode
  • todaysay
  • fastreplay

看到上面的参数,基本上就差不多知道签到请求所需要的东西了。
其中前面四个是固定的,所以无视。
然后跳到Form Data。参数名称大多都很明显了。

  • qdxq = 签到心情,即选择的心情图片
  • qdmode = 今天最想说模式
  • todaysay = 我今天最想说的内容
  • fastreplay = 快速回复

至于其中还有个formhash还不知道是什么参数,不过肯定是自己生成的,于是在页面元素里面搜索了一波。

接着百度了一波是怎么生成的。

看来想模拟生成这个是不太现实的了。
但是考虑到HTML文档里面有这个参数,所以把他提取出来,然后拼接请求以下。
https://域名/plugin.php?id=dsu_paulsign:sign&operation=qiandao&inajax=1&qdxq=kx&qdmode=2&todaysay=&fastreply=1&formhash=d3103290
得到以下的链接,然后放在浏览器里面请求一下。

看样子请求是成功的了。
接着我们的思路就出来了。

  1. 登录获取Cookie(貌似Dz的Cookie没有对失效时间做判断,所以可以一直用)
  2. 先模拟请求一次获取formhash
  3. 将获取到的formhash拼接,然后再请求一次。
  4. 签到成功。
    为防止小白,在文章的末尾附上各个参数的内容的获取方式。

代码

由于本人主修Java,所以代码使用Java来完成。
其中用于提取formhash的正则表达式为:

<input type="hidden" name="formhash" value="(.*?)" />

获取formhash

    public static String getFormHash(String link,String cookie) throws Exception{
        URL url = new URL(link);
        HttpURLConnection connection =  (HttpURLConnection)url.openConnection();
        connection.setConnectTimeout(5000);
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3754.400 QQBrowser/10.5.4020.400");
        connection.setRequestProperty("Cookie", cookie);
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line = null;
        StringBuilder response = new StringBuilder();
        while((line = reader.readLine())!=null){
            response.append(line);
        }
        Pattern pattern = Pattern.compile("<input type=\"hidden\" name=\"formhash\" value=\"(.*?)\" />");
        Matcher matcher = pattern.matcher(response.toString());
        String formhash = null;
        if (matcher.find()) {
            formhash = matcher.group(1);
            }
        return formhash;
    }

获取到了formhash后就可以签到了,代码如下:

    public static void sign(String link, String cookie,String formhash) throws Exception{
        URL url = new URL(link + "&operation=qiandao&inajax=1&qdxq=kx&qdmode=2&todaysay=&fastreply=1&formhash=" + formhash);
        HttpURLConnection connection =  (HttpURLConnection)url.openConnection();
        connection.setConnectTimeout(5000);
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3754.400 QQBrowser/10.5.4020.400");
        connection.setRequestProperty("Cookie", cookie);
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line = null;
        StringBuilder response = new StringBuilder();
        while((line = reader.readLine())!=null){
            response.append(line);
        }
        System.out.println(response.toString());
    }

后面几段打印的代码其实可以删除掉。
附上完整的代码:

package app;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class App {
    
    public static void main(String[] args) throws Exception {
        String link = "https://域名/plugin.php?id=dsu_paulsign:sign";
        String cookie = "";
        sign(link, cookie, getFormHash(link, cookie));
    }
    public static String getFormHash(String link,String cookie) throws Exception{
        URL url = new URL(link);
        HttpURLConnection connection =  (HttpURLConnection)url.openConnection();
        connection.setConnectTimeout(5000);
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3754.400 QQBrowser/10.5.4020.400");
        connection.setRequestProperty("Cookie", cookie);
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line = null;
        StringBuilder response = new StringBuilder();
        while((line = reader.readLine())!=null){
            response.append(line);
        }
        Pattern pattern = Pattern.compile("<input type=\"hidden\" name=\"formhash\" value=\"(.*?)\" />");
        Matcher matcher = pattern.matcher(response.toString());
        String formhash = null;
        if (matcher.find()) {
            formhash = matcher.group(1);
            }
        return formhash;
    }
    public static void sign(String link, String cookie,String formhash) throws Exception{
        URL url = new URL(link + "&operation=qiandao&inajax=1&qdxq=kx&qdmode=2&todaysay=&fastreply=1&formhash=" + formhash);
        HttpURLConnection connection =  (HttpURLConnection)url.openConnection();
        connection.setConnectTimeout(5000);
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3754.400 QQBrowser/10.5.4020.400");
        connection.setRequestProperty("Cookie", cookie);
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String line = null;
        StringBuilder response = new StringBuilder();
        while((line = reader.readLine())!=null){
            response.append(line);
        }
        System.out.println(response.toString());
    }
}

别忘了使用的时候把域名和Cookie替换掉。
对了,为了方便起见没有处理异常,有需求的话自己处理一下。
部署云函数的时候发现我是真的用不来腾讯云的云函数部署。然后把上面代码用php重构了一下。

<?php
  
    function discuz_sign(){
        function get_response($url,$cookie)
        {
              $curl = curl_init(); 
                curl_setopt($curl, CURLOPT_URL, $url);
                curl_setopt($curl, CURLOPT_HEADER, 0);
                curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($curl,CURLOPT_COOKIE,$cookie);
                curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 
                curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);  
                $response = curl_exec($curl);  
                curl_close($curl);
                return $response;
            
        }
        $link = 'https://域名/plugin.php?id=dsu_paulsign:sign';
        $cookie = '';
        $response = get_response($link,$cookie);
        preg_match_all('<input type="hidden" name="formhash" value="(.*?)" />', $response, $match);
        $formhash = $match[1][0];
        $result = get_response($link . '&operation=qiandao&inajax=1&qdxq=kx&qdmode=2&todaysay=&fastreply=1&formhash=' . $formhash,$cookie);
        echo $result;
    }
?>

部署云函数

鉴于不会用云函数部署Java项目(各种奇葩报错),所以这里使用PHP来部署。
云函数官网:https://cloud.tencent.com/product/scf/

部署

函数服务-新建
环境选PHP5.6

然后把上面的php代码的link和cookie修改后复制到代码框里。
执行方法改成方法名。

创建完成后,在函数代码里测试一下看能不能用。出现下图类似的就成功了。

触发

由于签到是每天一次,所以只需要每天触发一次就行了。
点击触发方式-添加触发方式-定时触发-自定义触发周期
表达式设置成:0 0 12 * * * * (每天12点)
保存

想设置其他周期的话参考腾讯云的Cron文档。

其他

为了节省资源,函数配置里修改一下资源占用。
点击编辑,主要调整内存和超时时间就行了。内存选择最小即可,超时时间根据网站相应速度来填写。

参数内容获取

获取cookie

登录dz按下f12,在右边选择Network。然后刷新。

加载完成后在下面列表框种随便找一个可能带有Cookie的请求。
比如后面带了php的。

点击Headers然后往下拉,找到红框中的内容就是cookie了。

全部复制出来就行了。


NOTE: 文章若无特别说明均为原创文章,如果要转载请保留出处!
0 #Code
分享