思路:

一波未平一波又起, 拿到这个需求的时候对我来说还是有挑战的,因为我之前并没有做过这种东西,不过我知道,实现这种需求所用的技术无非就是爬虫,爬虫我还是用过的,以前用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的不多。

Discuz论坛 自动加好友留言程序的更多相关文章

  1. jQuery自动加载更多程序

    1.1.1 摘要 现在,我们经常使用的微博.微信或其他应用都有异步加载功能,简而言之,就是我们在刷微博或微信时,移动到界面的顶端或低端后程序通过异步的方式进行加载数据,这种方式加快了数据的加载速度,由 ...

  2. jQuery自动加载更多程序(转)

    jQuery自动加载更多程序   1.1.1 摘要 现在,我们经常使用的微博.微信或其他应用都有异步加载功能,简而言之,就是我们在刷微博或微信时,移动到界面的顶端或低端后程序通过异步的方式进行加载数据 ...

  3. centos MySQL主从配置 ntsysv chkconfig setup命令 配置MySQL 主从 子shell MySQL备份 kill命令 pid文件 discuz!论坛数据库读写分离 双主搭建 mysql.history 第二十九节课

    centos  MySQL主从配置 ntsysv   chkconfig  setup命令  配置MySQL 主从 子shell  MySQL备份  kill命令  pid文件  discuz!论坛数 ...

  4. Line云端全自动加好友机器人

    一个 LINE 帐号可以加入 5,000 名好友,让这些 5,000 名好友收到 LINE 的主动提醒,好友会看到我的头像.主页照片.姓名与状态消息等,这种行为称为 LINE 的曝光. 如果我们要针对 ...

  5. php spl_autoload_register 实现自动加载

    spl_autoload_register (PHP 5 >= 5.1.2, PHP 7) spl_autoload_register - 注册给定的函数作为 __autoload 的实现 语法 ...

  6. Web QQ自动强制加好友代码

    也许见过强行聊天的代码:  tencent://Message/?Uin=574201314&websiteName=www.oicqzone.com&Menu=yes 但是你应该不知 ...

  7. QQ自动强制加好友代码html

    鲜为人知的QQ自动强制加好友代码 是的,你也许见过强行聊天的代码: tencent://Message/?Uin=574201314&websiteName=www.oicqzone.com& ...

  8. [转]在BBB启动时自动加载dtbo(或执行脚本、运行程序)

    启动时自动加载dtbo,实际上就是做了一个cape.官方推荐的方法是用eeprom来实现,请参考我的博文<为BBB制作专属自己的cape(一)>和<为BBB制作专属自己的cape(四 ...

  9. Dockfile自动创建discuz论坛和可道云

    将discuz论坛的zip包解压之后用tar包压缩,这样ADD可以直接解压tar包. [root@localhost centos6.9_ssh_discuz]# pwd /opt/dockerfil ...

随机推荐

  1. shell脚本开发基本规范

    当你的才华还撑不起你的野心的时候,你就应该静下心来学习.当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练.问问自己,想要怎样的人生. 欢迎加入 基础架构自动化运维:598432640,大数据S ...

  2. 【koa2基础框架封装】基于Proxy路由按需加载器和初始加载器

    我们在使用koa2做路由拦截后一般都习惯于直接将查找对应处理函数的过程映射到项目的文件夹目录,如: router.get('/test', app.controller.index.test); ap ...

  3. python爬虫之快速对js内容进行破解

    python爬虫之快速对js内容进行破解 今天介绍下数据被js加密后的破解方法.距离上次发文已经过去半个多月了,我写文章的主要目的是把从其它地方学到的东西做个记录顺便分享给大家,我承认自己是个懒猪.不 ...

  4. Python编程菜鸟成长记--A1--03--Python 环境安装(待完成)

    1.重点知识 Windows 上如何安装 Python 3 Linux 上如何安装 Python 3 Mac 上如何安装 Python 3 Windows 上如何安装 Pycharm Mac 上如何安 ...

  5. Ural 2072:Kirill the Gardener 3(DP)

    http://acm.timus.ru/problem.aspx?space=1&num=2072 题意:有n朵花,每朵花有一个饥渴值.现在浇花,优先浇饥渴值小的(即从小到大浇),浇花需要耗费 ...

  6. easyui datagrid 单元格 编辑时 事件 修改另一单元格

    //datagrid 列数据 $('#acc').datagrid({ columns : [ [ { field : 'fee_lend', title : '收费A', width : 100, ...

  7. java LineNumberReader的使用

    前段时间需要读报表打印,需求是可以从第N行读到第N行,发现百度出来的LineNumberReader方法都不怎么理想 然后就找到一篇和众百度里脱颖而出的好文章,所以分享之:   从类 的命名来看,貌似 ...

  8. MYSQL Got error 28 from storage engine

    网络查找该异常信息,发现 Got error 28 from storage engine 查了一下,数据库文件所在的盘应该没事,应该是数据库用的临时目录空间不够 引用 磁盘临时空间不够导致. 解决办 ...

  9. EnjoyingSoft之Mule ESB开发教程第四篇:Mule Expression Language - MEL表达式

    目录 1. MEL的优势 2. MEL的使用场景 3. MEL的示例 4. MEL的上下文对象 5. MEL的Variable 6. MEL访问属性 7. MEL操作符 本篇主要介绍Mule表达式语言 ...

  10. wpf怎么绑定多个值,多个控件

    最近有不少wpf新手问wpf的命令怎么绑定多个控件,很多人为此绞尽脑汁,网上的答案找了也没找到靠谱的,其实用MultiBinding就可以了.从.net 3.0版本开始,就支持MultiBinding ...