思路:

一波未平一波又起, 拿到这个需求的时候对我来说还是有挑战的,因为我之前并没有做过这种东西,不过我知道,实现这种需求所用的技术无非就是爬虫,爬虫我还是用过的,以前用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. ASP.Net Core2.1 秒杀项目一步一步实现CI/CD系列一

    前言:有一段时间没写博客了,那是因为博主菜,需要学习和准备,这不带来了本系列的文章.在这里我把学习的心得分享出来,有些点理解的也不是太到位,希望大佬们能多多给点建议和指导.下半年就把这个系列的文章写完 ...

  2. python的比较关系运算符和逻辑运算符

    比较运算符 运算符 描述 示例 == 检查两个操作数的值是否相等,如果是则条件变为真. 如a=2,b=2则(a == b) 为 true. != 检查两个操作数的值是否相等,如果值不相等,则条件变为真 ...

  3. 我是这么学习Selenium元素定位操作的

    写在前面 做web自动化测试都有体会,本质也就是通过操作页面元素对象来模拟用户操作行为,那么首先我们先找到这些元素对象,然后才能进行一系列操作. 我们得先告诉自动化工具或者说代码要操作那个元素,毕竟代 ...

  4. Vue技术点整理-Vue Router

    路由 Vue Router 对于单页面应用来说,如果涉及到多个页面的话,就必须要使用到路由,一般使用官方支持的 vue-router 库 一,Vue Router 在项目中的安装引用 1,在页面中使用 ...

  5. cookie 和 session 设置

    cookie: 保存在浏览器上的一组键值对, 是由服务器让浏览器进行设置的 下次浏览器访问的时候会携带cookie. request是客户端请求, response是服务端响应. 读取客户端的cook ...

  6. scrapy实战5 POST方法抓取ajax动态页面(以慕课网APP为例子):

    在手机端打开慕课网,fiddler查看如图注意圈起来的位置 经过分析只有画线的page在变化 上代码: items.py import scrapy class ImoocItem(scrapy.It ...

  7. 9.18考试 第三题chess题解

    在讲这道题之前我们先明确一个丝薄出题人根本没有半点提示却坑死了无数人的注意点: 走敌人和不走敌人直接到时两种走法,但只走一个敌人和走一大坨敌人到同一个点只算一种方案(当然,前提是步骤一致). 当时看完 ...

  8. 微信小程序之楼层效果

    今天做了一个小程序实现一个楼层效果  带大家分享下经验和api的使用吧 如图 将左边和右边各分了一个组件  目录如下 其中list页面是这个楼层效果的页面 components是组成这个页面的两个组件 ...

  9. python中变量在内存中的存储与地址关系解析、浅度/深度copy、值传递、引用传递

    ---恢复内容开始--- 1.变量.地址 变量的实现方式有:引用语义.值语义 python语言中变量的实现方式就是引用语义,在变量里面保存的是值(对象)的引用(值所在处内存空间的地址).采用这种方式, ...

  10. Maven(三)使用 IDEA 创建一个 Maven 项目

    利用 IDEA 创建一个 Maven 项目 创建 Maven 项目 选择 File --> New --> Project 选中 Maven 填写项目信息 选择工作空间 目录结构 ├─sr ...