iQQ 学习笔记声明
本文仅供学习研究使用,不得用于任何非法及侵权用途。
转贴请注明原发位置: http://xuekaiyuan.com/forum.php?mod=viewthread&tid=5
讨论请加QQ群:306320259


iQQ 学习笔记2说明 :借助新浪微博输入验证码、远程控制退出
在第1个案例中实现了iQQ的登录、验证码和收消息,其中有两处需要人工参与,第一处是需要打开验证码图片,然后输入验证码,第二处是退出程序需要强制退出。验证码暂时还不能自动识别,不过可以改进交互方式,本例中将借助新浪微博实现显示验证码图片和输入验证码。退出程序改成收到QQ消息后按消息内容操作。


iQQ 学习笔记2程序 :借助新浪微博输入验证码、远程控制退出
这是主程序,其中的username常量的值应替换为QQ号,password常量的值应替换为该QQ号对应的QQ密码。

package test_2;import java.util.logging.Logger;import iqq.im.QQClient;
import iqq.im.QQException;
import iqq.im.QQNotifyListener;
import iqq.im.WebQQClient;
import iqq.im.actor.ThreadActorDispatcher;
import iqq.im.bean.QQMsg;
import iqq.im.bean.QQStatus;
import iqq.im.bean.content.ContentItem;
import iqq.im.bean.content.TextItem;
import iqq.im.event.QQActionEvent;
import iqq.im.event.QQActionFuture;
import iqq.im.event.QQNotifyEvent;
import iqq.im.event.QQNotifyEventArgs;
import iqq.im.event.QQActionEvent.Type;public class Test_2 {private static final String username = "**********";private static final String password = "**********";private static final Logger logger = java.util.logging.Logger.getLogger("");private static QQClient client;public static void main(String[] args) {client = new WebQQClient(username, password, new QQNotifyListener() {@Overridepublic void onNotifyEvent(QQNotifyEvent event) {if (event.getType() == QQNotifyEvent.Type.CHAT_MSG) {if (event.getTarget() instanceof QQMsg) {QQMsg msg = (QQMsg) event.getTarget();for (ContentItem contentItem : msg.getContentList()) {if (contentItem instanceof TextItem) {TextItem textItem = (TextItem) contentItem;logger.info(textItem.getContent());if (textItem.getContent().startsWith("logout ")) {client.logout(null);}                                 }}}} else if (event.getType() == QQNotifyEvent.Type.CAPACHA_VERIFY) {if (event.getTarget() instanceof QQNotifyEventArgs.ImageVerify) {QQNotifyEventArgs.ImageVerify imageVerify = (QQNotifyEventArgs.ImageVerify) event.getTarget();String code = ImageVerifyQuestioners.ImageVeiryQuestion(imageVerify);client.submitVerify(code, event);} else {logger.info(event.getTarget().getClass().getName());}} else {logger.info("TODO QQNotifyEvent: " + event.getType() + ", " + event.getTarget());}}}, new ThreadActorDispatcher());QQActionFuture future = client.login(QQStatus.ONLINE, null);try {QQActionEvent event = future.waitFinalEvent();if (event.getType() == Type.EVT_OK) {client.beginPollMsg();}} catch (QQException e) {e.printStackTrace();}}
}

为了便于实现多种图片验证码的输入方式,设计一个图片验证码接口。

package test_2;import iqq.im.event.QQNotifyEventArgs.ImageVerify;public abstract class ImageVerifyQuestioner {private ImageVerify imageVerify;private String Code;public ImageVerifyQuestioner(ImageVerify imageVerify) {this.imageVerify = imageVerify;this.Code = "";}protected final ImageVerify getImageVerify() {return imageVerify;}public final String getCode() {return Code;}protected final void setCode(String code) {Code = code;}public abstract void loop ();
}

通过一个调度程序管理多种图片验证码的输入方式,当一种输入方式获取验证码时,其他输入方式退出。

package test_2;import java.util.ArrayList;
import java.util.List;import iqq.im.event.QQNotifyEventArgs.ImageVerify;public class ImageVerifyQuestioners {public static String ImageVeiryQuestion (ImageVerify imageVerify) {String code = "";List<ImageVerifyQuestioner> imageVerifyQuestionerList = new ArrayList<ImageVerifyQuestioner>();imageVerifyQuestionerList.add(new ImageVerifyConsoleQuestioner(imageVerify));imageVerifyQuestionerList.add(new ImageVerifyWeiboQuestioner(imageVerify));boolean alive = true;while (alive) {for(ImageVerifyQuestioner imageVerifyQuestioner : imageVerifyQuestionerList) {if (true == alive) {imageVerifyQuestioner.loop();if (imageVerifyQuestioner.getCode() != "") {code = imageVerifyQuestioner.getCode();alive = false;}                   }}try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}return code;}
}

保持原有的命令行交互输入图片验证码的输入方式。

/*** */
package test_2;import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;import iqq.im.event.QQNotifyEventArgs.ImageVerify;public class ImageVerifyConsoleQuestioner extends ImageVerifyQuestioner {private boolean isPrompt;private StringBuilder codeStringBuilder = new StringBuilder();public ImageVerifyConsoleQuestioner(ImageVerify imageVerify) {super(imageVerify);}private void prompt () {try {ImageIO.write(this.getImageVerify().image, "png", new File("verify.png"));System.out.println(this.getImageVerify().reason);System.out.print("请输入在项目根目录下 verify.png 图片里面的验证码: ");isPrompt = true;} catch (IOException e) {e.printStackTrace();}}private void read () {try {int available = System.in.available();if (0 < available) {int inChar = System.in.read();switch (Character.getType(inChar)) {case Character.UPPERCASE_LETTER:case Character.LOWERCASE_LETTER:case Character.DECIMAL_DIGIT_NUMBER:codeStringBuilder.append((char) inChar);break;case Character.CONTROL:this.setCode(codeStringBuilder.toString());break;}}} catch (IOException e) {e.printStackTrace();}}@Overridepublic void loop() {if (false == this.isPrompt) {this.prompt();}if (this.getCode() == "") {this.read();                 }       }
}

新增通过新浪微博输入图片验证码的输入方式,其中的accessTokenFile的值应替换为保存新浪微博Access Token的路径。

/*** */
package test_2;import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Logger;import javax.imageio.ImageIO;
import javax.net.ssl.HttpsURLConnection;import org.json.JSONObject;import iqq.im.event.QQNotifyEventArgs.ImageVerify;public class ImageVerifyWeiboQuestioner extends ImageVerifyQuestioner {private static final String accessTokenFile = "**********";private static final Logger logger = java.util.logging.Logger.getLogger("");private String accessToken;private long weiboId;private long lastCheckTime;public ImageVerifyWeiboQuestioner(ImageVerify imageVerify) {super(imageVerify);}private void readAccessToken () {FileReader fileReaderAccessToken;try {fileReaderAccessToken = new FileReader(accessTokenFile);BufferedReader bufferedReaderAccessToken = new BufferedReader(fileReaderAccessToken);accessToken = bufferedReaderAccessToken.readLine();bufferedReaderAccessToken.close();fileReaderAccessToken.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}private void uploadVerifyImage () {try {//StatusStringBuilder statusStringBuilder = new StringBuilder();statusStringBuilder.append("请@胡争辉 输入验证码 ");statusStringBuilder.append((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date())); //URLStringBuilder urlStringBuilder = new StringBuilder();urlStringBuilder.append("https://api.weibo.com/2/statuses/upload.json?access_token=");urlStringBuilder.append(accessToken);URL url = new URL(urlStringBuilder.toString());URLConnection urlConnection =url.openConnection();if (urlConnection instanceof HttpsURLConnection) {String BOUNDARY = "---------------------------" + String.valueOf(System.currentTimeMillis());ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byteArrayOutputStream.write(("--" + BOUNDARY + "\r\n").getBytes());byteArrayOutputStream.write(("Content-Disposition: form-data; name=\"pic\"; filename=\"verifyimage.png\"\r\n").getBytes());byteArrayOutputStream.write(("Content-Type: image/png\r\n").getBytes());byteArrayOutputStream.write(("\r\n").getBytes());ImageIO.write(this.getImageVerify().image, "png", byteArrayOutputStream);byteArrayOutputStream.write(("\r\n").getBytes());byteArrayOutputStream.write(("--" + BOUNDARY + "\r\n").getBytes());byteArrayOutputStream.write(("Content-Disposition: form-data; name=\"status\"\r\n").getBytes());byteArrayOutputStream.write(("\r\n").getBytes());byteArrayOutputStream.write(statusStringBuilder.toString().getBytes());byteArrayOutputStream.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes());HttpsURLConnection httpsURLConnection = (HttpsURLConnection) urlConnection;httpsURLConnection.setRequestMethod("POST");httpsURLConnection.addRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);httpsURLConnection.setDoOutput(true);httpsURLConnection.setDoInput(true);OutputStream outputStream = httpsURLConnection.getOutputStream();outputStream.write(byteArrayOutputStream.toByteArray());outputStream.flush();outputStream.close();StringBuilder response = new StringBuilder();InputStreamReader inputStreamReader = new InputStreamReader(httpsURLConnection.getInputStream());int readChar = inputStreamReader.read();while (-1 != readChar) {response.append((char) readChar);readChar = inputStreamReader.read();}inputStreamReader.close();httpsURLConnection.disconnect();logger.info(response.toString());JSONObject responseJson = new JSONObject(response.toString());this.weiboId = responseJson.getLong("id"); logger.info("Weibo Id = " + String.valueOf(this.weiboId));}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}private void checkComment () {try {StringBuilder commentStringBuilder = new StringBuilder();commentStringBuilder.append("https://api.weibo.com/2/comments/show.json?filter_by_author=1&access_token=");commentStringBuilder.append(accessToken);commentStringBuilder.append("&id=");commentStringBuilder.append(weiboId);URL comment = new URL(commentStringBuilder.toString());URLConnection commentConnection = comment.openConnection();if (commentConnection instanceof HttpsURLConnection) {HttpsURLConnection commentHttpsURLConnection = (HttpsURLConnection) commentConnection;commentHttpsURLConnection.setDoInput(true);InputStreamReader commentStreamReader = new InputStreamReader(commentHttpsURLConnection.getInputStream());StringBuilder commentResponse = new StringBuilder();int commentChar = commentStreamReader.read();while (-1 != commentChar) {commentResponse.append((char) commentChar);commentChar = commentStreamReader.read();}commentStreamReader.close();commentHttpsURLConnection.disconnect();JSONObject commentsJson = new JSONObject(commentResponse.toString());int total_number = commentsJson.getInt("total_number");logger.info("total_number = " + String.valueOf(total_number));if (0 < total_number) {JSONObject commentJson = commentsJson.getJSONArray("comments").getJSONObject(0);logger.info("text=" + commentJson.getString("text"));this.setCode(commentJson.getString("text"));}}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void loop () {if (null == accessToken) {this.readAccessToken();}if ((null != accessToken) && (0 == weiboId)) {this.uploadVerifyImage();lastCheckTime = System.currentTimeMillis();}if ((0 < weiboId) && (this.getCode() == "") && (10000 < System.currentTimeMillis() - lastCheckTime)) {this.checkComment();lastCheckTime = System.currentTimeMillis();}}
}

iQQ 学习笔记2测试 :借助新浪微博输入验证码、远程控制退出
测试本程序需要注册两个QQ号,并互相加为好友。保持一个QQ使用客户端登录,另一个QQ的QQ号和密码填写在程序中。
需要注册一个新浪微博APP帐号,需要注册两个新浪微博帐号,其中一个通过该新浪微博APP验证后保存Access Token,设定这两个帐号互相关注。
运行程序后不仅出现命令行提示,还将用一个新浪微博帐号发一条微博,另一个新浪微博帐号会显示该条微博,微博上包含有验证码图片,用另一个新浪微博帐号回复该条微博,内容为验证码图片上的文字。
在QQ上可以看到该QQ上线,如果输入logout,QQ将下线,程序自动退出。

iQQ 学习笔记2 :借助新浪微博输入验证码、远程控制退出相关推荐

  1. iQQ 学习笔记1 :登录、验证码、收消息

    iQQ 学习笔记声明 本文仅供学习研究使用,不得用于任何非法及侵权用途. 转贴请注明原发位置: http://xuekaiyuan.com/forum.php?mod=viewthread&t ...

  2. iQQ 学习笔记3 :编写代码打包Ant脚本

    iQQ 学习笔记声明 本文仅供学习研究使用,不得用于任何非法及侵权用途. 转贴请注明原发位置: http://xuekaiyuan.com/forum.php?mod=viewthread&t ...

  3. Windows phone 8 学习笔记(1) 触控输入

    Windows phone 8 学习笔记(1) 触控输入 原文:Windows phone 8 学习笔记(1) 触控输入 Windows phone 8 的应用 与一般的Pc应用在输入方式上最大的不同 ...

  4. Python3 基础学习笔记 C06【用户输入和 while 循环】

    CSDN 课程推荐:<8小时Python零基础轻松入门>,讲师齐伟,苏州研途教育科技有限公司CTO,苏州大学应用统计专业硕士生指导委员会委员:已出版<跟老齐学Python:轻松入门& ...

  5. Vue学习笔记(六) 表单输入绑定

    v-model 指令在表单元素上创建双向数据绑定,它负责用于监听用户输入事件以更新数据 注意,v-model 会忽略所有表单元素特性的初始值,而总是将 Vue 实例的数据作为数据来源 1.输入框 &l ...

  6. Latex学习笔记——常用符号的输入

    我的Latex学习笔记 箭头符号 集合符号 数学运算符号 箭头符号 符号 代码 右箭头→\rightarrow→ \rightarrow 左箭头←\leftarrow← \leftarrow 右推出符 ...

  7. 《Python编程从入门到实践》学习笔记7:用户输入和while循环

    一.用户输入 函数input()的功能,就是让程序在运行过程中,能够接收到用户的输入进行输出,如下例所示: prompt = "请按照提示输入您的姓名,我们将根据您的姓名显示信息!\n&qu ...

  8. 爬虫学习笔记(十七)—— 字符验证码

    文章目录 一.认识验证码 1.1.概念 1.2.作用 1.3.类别 二.Pillow库 2.1.PIL库和Pillow库 2.1.1.Pillow库安装 2.1.2.PIL与Pillow使用注意 2. ...

  9. Struts2学习笔记(十九) 验证码

    概述 验证码也是我们在web应用中经常要用到的功能.基本思路就是,我们在服务端动态的生一成张图片,然后将它输出到客户端.图片上包含一些字符信息,我们将这些字符信息事先保存在session中,那么客户端 ...

最新文章

  1. Android视图动画集合AndoridViewAnimations
  2. 项目乱码 GBK转UTF-8工具
  3. CentOS 7安装教程(图文详解)如下
  4. firefox ie table 布局 兼容性问题
  5. Kruskal Prim模板
  6. 深度学习总结:GAN,原理,算法描述,pytoch实现
  7. Insertion Sort List,Merge Two Sorted Lists,Sort List
  8. Flutter入门:动画相关
  9. 物联网应用:蓝牙模块在智能门锁中的应用
  10. vim 基础学习之文件跳转
  11. 【转】国密算法sm4 CBC模式加解密
  12. 特征向量的辨析(数学,机器学习)
  13. C语言在main中输入2个整数ab,请教一个C语言问题。若输入3个整数3,2,1,则以下程序输出的结果是.,c 语言问题 输入三个整数 按从小到大输出...
  14. Computational Social Science计算社会学-《Science》文章翻译
  15. Xilinx FPGA PTP IEEE1588使用
  16. 百度地图通过经纬度坐标绘制移动路径轨迹
  17. Java存储金额解决方案BigDecimal
  18. 第五章: 项目范围管理
  19. OpenStack核心组件原理与应用之Glance
  20. 萨提亚·纳德拉与沈向洋CVPR对谈:那些未来可期的计算机视觉研究与应用

热门文章

  1. nvme固态硬盘安装win10填坑记
  2. 【CISSP备考】第七章-安全运营
  3. 2015校园招聘360失败的惨痛经历
  4. 【Eclipse】xml文件
  5. World Streamer学习1
  6. 学生信息管理系统设计
  7. 电容-贴片陶瓷电容的NPO、C0G、X7R、X5R、Y5V、Z5U
  8. pytest框架用主函数方式运行报错No module named ‘_pytest.resultlog‘
  9. 京东裁员10%的高管
  10. 在Winform中上传文件的工具类-ResourceMgr