java HttpClient+Jsoup打造灌水利器再也不怕起火了

不知道多久以前就有过写个自动回帖的小软件一直没有实现,最近闲下来了遂研究了下,本人小菜对于HTTP协议一知半解只能在请教google大神了,把我的想法跟google大神说了之后,google大神说这小子不错,这是为防火事业做贡献啊!特赐予小弟以下神器:

1、HttpClient 4.3.1 (GA)

以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见 HttpClient 的主页。

  • 实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
  • 支持自动转向
  • 支持 HTTPS 协议
  • 支持代理服务器等

2、Jsoup

jsoup 的主要功能如下

  • 从一个 URL,文件或字符串中解析 HTML
  • 使用 DOM 或 CSS 选择器来查找、取出数据
  • 可操作 HTML 元素、属性、文本
  • 使用与jquery几乎一样的语法

废话不多说直接进入正题,在HTTPClient源码包内包含example文件夹此文件夹内包含一些基本用法这些例子入门足够了找到ClientFormLogin.java具体解释注释已经很清楚了大致意思就是模拟HTTP请求存储cookies。

测试网站:http://bbs.dakele.com/

因为此网站对登录做了特殊处理所以与标准的DZ论坛可能会有些出入请自行修改

对网站的分析使用的chrome自带的审查元素,这个折腾了不少时间

登录地址:http://passport.dakele.com/login.do?product=bbs

输入错误的用户名和密码会发现实际登录地址为http://passport.dakele.com/logon.do 注意【i/n的区别刚开始没注意以为见鬼了】

返回错误信息

{"err_msg":"帐号或密码错误"}

输入正确信息返回

{"result":true,"redirect":http://bbs.dakele.com/member.php?mod=logging&action=login&loginsubmit=yes&infloat=yes&lssubmit=yes&inajax=0&fastloginfield=username&quickforward=yes&handlekey=ls&cookietime=2592000&remember=0&username=youname&AccessKey=[]}

直接输入rediret连接和正常登录

获取跳转链接:

1private LoginResult getRedirectUrl(){ 2 LoginResult loginResult = null; 3 CloseableHttpClient httpClient = HttpClients.createDefault(); 4 HttpPost httpost = new HttpPost(LOGINURL); 5 httpost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); 6 httpost.setHeader("Accept-Language", "zh-CN,zh;q=0.8"); 7 httpost.setHeader("Cache-Control", "max-age=0"); 8 httpost.setHeader("Connection", "keep-alive"); 9 httpost.setHeader("Host", "passport.dakele.com"); 10 httpost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36"); 11 List <NameValuePair> nvps = new ArrayList <NameValuePair>(); 12 nvps.add(new BasicNameValuePair("product", "bbs")); 13 nvps.add(new BasicNameValuePair("surl", "http://bbs.dakele.com/")); 14 nvps.add(new BasicNameValuePair("username", "yourname"));//用户名 15 nvps.add(new BasicNameValuePair("password", "yourpass"));//密码 16 nvps.add(new BasicNameValuePair("remember", "0")); 17 18 httpost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); 19 CloseableHttpResponse response2 = null; 20 try { 21 response2 = httpClient.execute(httpost); 22 if(response2.getStatusLine().getStatusCode()==200){ 23 HttpEntity entity = response2.getEntity(); 24 String entityString = EntityUtils.toString(entity); 25 JSONArray jsonArray = JSONArray.fromObject("["+entityString+"]"); 26 JsonConfig jsonConfig=new JsonConfig(); 27 jsonConfig.setArrayMode(JsonConfig.MODE_OBJECT_ARRAY); 28 jsonConfig.setRootClass(LoginResult.class); 29 LoginResult[] results= (LoginResult[]) JSONSerializer.toJava( jsonArray, jsonConfig ); 30 if(results.length==1){ 31 loginResult = results[0]; 32 } 33 } 34 } catch (ClientProtocolException e) { 35 e.printStackTrace(); 36 } catch (IOException e) { 37 e.printStackTrace(); 38 }finally{ 39 try { 40 response2.close(); 41 httpClient.close(); 42 } catch (IOException e) { 43 e.printStackTrace(); 44 } 45 } 46 return loginResult; 47 }

登录代码:

1public boolean login(){ 2 boolean flag = false; 3 LoginResult loginResult = getRedirectUrl(); 4 if(loginResult.getResult().equals("true")){ 5 cookieStore = new BasicCookieStore(); 6 globalClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build(); 7 HttpGet httpGet = new HttpGet(loginResult.getRedirect()); 8 httpGet.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); 9 httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.8"); 10 httpGet.setHeader("Connection", "keep-alive"); 11 httpGet.setHeader("Host", HOST); 12 httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36"); 13 try { 14 globalClient.execute(httpGet); 15 } catch (ClientProtocolException e) { 16 e.printStackTrace(); 17 } catch (IOException e) { 18 e.printStackTrace(); 19 } 20 List<Cookie> cookies2 = cookieStore.getCookies(); 21 if (cookies2.isEmpty()) { 22 log.error("cookie is empty"); 23 } else { 24 for (int i = 0; i < cookies2.size(); i++) { 25 26 } 27 } 28 } 29 30 return flag; 31 }

到此已经登录成功可以进行只有登录号才能做的事了,什么?你不知道当然是灭火了

首先取得需要回复的帖子地址,列表页比较有规律所有没有写自动发现的所以写了个循环@1

1for(int i=1;i<200;i++){ 2 String basurl="http://bbs.dakele.com/forum-43-"+i+".html"; 3 log.info(basurl); 4 List<String> urls = dakele.getThreadURLs(basurl); 5 for(String url:urls){ 6 //log.info(url); 7 ReplayContent content = dakele.preReplay(url); 8 if(content!=null){ 9 log.info(content.getUrl()); 10 log.info(content.getMessage()); 11 //dakele.replay( content); 12 //Thread.sleep(15300); 13 } 14 } 15 }

在列表页内获取帖子地址:

1String html = EntityUtils.toString(entity); 2 Document document = Jsoup.parse(html,HOST); 3 Elements elements=document.select("tbody[id^=normalthread_] > tr > td.new > a.xst"); 4 for(int i=0;i<elements.size();i++){ 5 Element e = elements.get(i); 6 urList.add(e.attr("abs:href")); 7 }

在需要回复的帖子内获得需要提交的form表单地址以及构造回复内容

1public ReplayContent preReplay(String url){ 2 ReplayContent content = null; 3 HttpGet get = new HttpGet(url); 4 get.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); 5 get.setHeader("Accept-Language", "zh-CN,zh;q=0.8"); 6 get.setHeader("Connection", "keep-alive"); 7 get.setHeader("Host", HOST); 8 get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36"); 9 try { 10 CloseableHttpResponse response = globalClient.execute(get); 11 HttpEntity entity = response.getEntity(); 12 String html = EntityUtils.toString(entity); 13 Document document = Jsoup.parse(html, HOST); 14 Element postForm = document.getElementById("fastpostform"); 15 if(!postForm.toString().contains("您现在无权发帖")){ 16 content = new ReplayContent(); 17 content.setUrl(url); 18 19 log.debug(postForm.attr("abs:action")); 20 content.setAction(postForm.attr("abs:action")); 21 22 23 //////// 24 Elements teElements = document.select("td[id^=postmessage_]"); 25 String message = ""; 26 for(int i=0;i<teElements.size();i++){ 27 String temp = teElements.get(i).html().replaceAll( "(?is)<.*?>", ""); 28 if(temp.contains("发表于")){ 29 String[] me = temp.split("\\s+"); 30 temp = me[me.length-1]; 31 } 32 message+=temp.replaceAll("\\s+", ""); 33 } 34 log.debug(message.replaceAll("\\s+", "")); 35 /////////////// 36 /*取最后一条评论 37 Element messageElement= document.select("td[id^=postmessage_]").last(); 38// String message = messageElement.html().replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll("<[^>]*>", "").replaceAll("[(/>)<]", ""); 39 String message = messageElement.html().replaceAll( "(?is)<.*?>", ""); 40 */ 41 if(message.contains("发表于")){ 42 String[] me = message.split("\\s+"); 43 message = me[me.length-1]; 44 } 45 content.setMessage(message.replaceAll("&nbsp;", "").replaceAll("上传", "").replaceAll("附件", "").replaceAll("下载", "")); 46 Elements inputs = postForm.getElementsByTag("input"); 47 for(Element input:inputs){ 48 log.debug(input.attr("name")+":"+input.attr("value")); 49 if(input.attr("name").equals("posttime")){ 50 content.setPosttime(input.attr("value")); 51 }else if(input.attr("name").equals("formhash")){ 52 content.setFormhash(input.attr("value")); 53 }else if(input.attr("name").equals("usesig")){ 54 content.setUsesig(input.attr("value")); 55 }else if(input.attr("name").equals("subject")){ 56 content.setSubject(input.attr("value")); 57 } 58 } 59 }else{ 60 log.warn("您现在无权发帖:"+url); 61 } 62 } catch (ClientProtocolException e) { 63 e.printStackTrace(); 64 } catch (IOException e) { 65 e.printStackTrace(); 66 } 67 return content; 68 }

地址有了,内容有了接下来开始放水了

1public void replay(ReplayContent content){ 2 3 HttpPost httpost = new HttpPost(content.getAction()); 4 httpost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); 5 httpost.setHeader("Accept-Language", "zh-CN,zh;q=0.8"); 6 httpost.setHeader("Cache-Control", "max-age=0"); 7 httpost.setHeader("Connection", "keep-alive"); 8 httpost.setHeader("Host", HOST); 9 httpost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36"); 10 List <NameValuePair> nvps = new ArrayList <NameValuePair>(); 11 nvps.add(new BasicNameValuePair("posttime", content.getPosttime())); 12 nvps.add(new BasicNameValuePair("formhash", content.getFormhash())); 13 nvps.add(new BasicNameValuePair("usesig", content.getUsesig())); 14 nvps.add(new BasicNameValuePair("subject", content.getSubject())); 15 nvps.add(new BasicNameValuePair("message", content.getMessage())); 16 17 httpost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); 18 //HTTP 三次握手 必须处理响应刚开始没注意卡在这了 19 CloseableHttpResponse response2 = null; 20 21 try { 22 response2 = globalClient.execute(httpost); 23 //log.info(content.getAction()); 24 //log.info(content.getMessage()); 25 HttpEntity entity = response2.getEntity(); 26 EntityUtils.consume(entity); 27// BufferedWriter bw= new BufferedWriter(new FileWriter("d:/tt1.html")); 28// bw.write(EntityUtils.toString(response2.getEntity())); 29// bw.flush(); 30// bw.close(); 31 //System.out.println(EntityUtils.toString(response2.getEntity())); 32 } catch (ClientProtocolException e) { 33 e.printStackTrace(); 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } 37 38 }

当然这只适用于没有验证码的论坛对于有验证码的只能绕道了,

灌水有害,经过一番轰炸这就是结果QQ截图20140109224028

对于回复内容刚开始只取了当前帖子内最后一条评论然后进行回复,被警告!然后使用IK分词获取关键字代码是贴来的请移步

参考连接:

缺点:没有使用多线程、没有进行充分测试

代码整理中尽快提供

后期计划:加入签到、做任务功能、把@1循环改为自动发现

小弟第一次发帖其中有不足之处望批评指正

------------------------------------------

下载地址http://pan.baidu.com/s/1jGjwA5g

早上把代码整理了下,现在分享给大家,直接对Myeclipse工程进行的打包解压后可直接导入

修改IKFenci.java 内用户名和密码可直接运行

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Java爬虫之JSoup使用教程

title:Java爬虫之JSoup使用教程date:201812248:00:000800update:201812248:00:000800author:mecover:https://imgblog.csdnimg.cn/20181224144920712(https://www.oschin