Discuz论坛 自动加好友留言程序

思路:

一波未平一波又起, 拿到这个需求的时候对我来说还是有挑战的,因为我之前并没有做过这种东西,不过我知道,实现这种需求所用的技术无非就是爬虫,爬虫我还是用过的,以前用JSOUP写过一个爬小说的程序,在我的博客园可以看到: 
https://www.cnblogs.com/yangchaojie/p/9203876.html

这次不同,想要在论坛发消息首先是要登录的,所以必须要一个账号,接着是让爬虫登录,这是最重要的一个步骤,登录后获取Cookie存储,在加好友发消息的时候都要用到Cookie。

在开发过程中,遇到了不少难题,比如一开始的FormHash参数,这个参数一开始不知道哪里获取,最后发现登录后在页面源代码中就有。

FormHash是发送加好友等请求必须的参数,所以在爬虫模拟登录后,进行爬取FormHash值,接着再请求加好友链接。

代码:

登录,获取Cookie:

 public static Map<String, String> getCookie(String username, String password, String domain) throws Exception {
        SslUtils.ignoreSsl();
        Connection conn = Jsoup.connect(Address.getLoginUrl(username, password, domain));
        conn.method(Connection.Method.GET);
        conn.followRedirects(false);
        Connection.Response response;
        response = conn.execute();
        System.err.println(response.body());
        return response.cookies();
    }

 

获取FormHash:

 public static String getFormHash(String domain) throws Exception {
        SslUtils.ignoreSsl();
        Connection conn = Jsoup.connect(Address.getFormHash(domain));
        conn.followRedirects(false);
        Connection.Response response = conn.execute();
        String HTMLRes = response.body();
        String hashStr = "formhash=";
        int hashIndex = HTMLRes.lastIndexOf(hashStr);
        for (Map.Entry<String, String> c : response.cookies().entrySet()) {
            logger.info("Cookie:" + c.getKey() + "|" + c.getValue());
        }
        System.err.println(response.body());
        return HTMLRes.substring(hashIndex + hashStr.length(), hashIndex + hashStr.length() + 8);  //formhash为8个字节长度
    }

发送加好友请求并留言:

/**
     * @param cookies
     * @param touId 用户ID
     * @param msg 留言
     * @param log 日志
     * @param domain 域名
     * @param formHash Hash值
     * @throws Exception 
     */
    public static void hello(Map<String, String> cookies, String touId, String msg, TextArea log, String domain, String formHash) throws Exception {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                try {
                    log.appendText("HASH值获取:" + formHash + "\n");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        SslUtils.ignoreSsl();
        Connection conn = Jsoup.connect(Address.hello(touId, domain));
        for (Map.Entry<String, String> entry : cookies.entrySet()) {
            conn.cookie(entry.getKey(), entry.getValue());
        }
        conn.data("referer", Address.referer(touId, domain));
        conn.data("addsubmit", "true");
        conn.data("handlekey", String.format("a_friend_li_%S", touId));
        conn.data("formhash", formHash);
        conn.data("note", msg);
        conn.data("gid", "1");
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                log.appendText("开始发送:" + msg + "\t" + System.currentTimeMillis() + "\n");
            }
        });
        Document document = conn.post();
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                logger.info(document.text());
                if (document.text().contains("已发送") || document.text().contains("验证")) {
                    log.appendText("已发送" + "\n");
                } else {
                    log.appendText("发送失败!" + "\n");
                }
//                log.appendText(document.text());
            }
        });
    }

 

以上是这套流程的核心代码,最后将功能使用JavaFX展现:

 

完成。

弊端:

这个程序目前是可以实现功能的,但只能对某些防护较为薄弱的DZ论坛使用,而且如果登录遇到验证码,也是不行。

在GUI窗体中存在TextArea日志区运行久了会无法刷新出日志信息,这个问题暂时找不到答案,我也没时间研究这个,毕竟用JavaFX的不多。

 

posted @ 2019-08-06 23:08  杨超杰  阅读(526)  评论(0编辑  收藏  举报