webqq2协议分析和qq聊天机器人简单实现_第1页
webqq2协议分析和qq聊天机器人简单实现_第2页
webqq2协议分析和qq聊天机器人简单实现_第3页
webqq2协议分析和qq聊天机器人简单实现_第4页
webqq2协议分析和qq聊天机器人简单实现_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

\o"webqq2协议分析和qq聊天机器人简单实现"webqq2协议分析和qq聊天机器人简单实现发表于

梁龙

25February,2011

8368046764001D636F6E6E7365727665725F77656271714031302E3133332E332E3234300000235100000B79026E040043F60C166D0000000A404746365677767041316D00000028F72A8722C988252AEF4E0268F1D26A3D647F06F6

FF353A5C6CDAAA49ABB2FCDF0CEE2D8D64373AC2"}}

记住其中的psessionid。后面在发送消息和获取qq消息都需要这个参数。

4。发送一个qq消息给好友

地址:/channel/send_msg

同样是post:r={"to":qq号码,"face":0,"content":"[\"23\",[\"font\",{\"name\":\"宋体\",\"size\":\"10\",\"style\":

[0,0,0],\"color\":\"000000

\"}]]","msg_id":7780001,"clientid":"15778909","psessionid":"8368046764001D636F6E6E7365727665725F77656271714031302E3133332E332E3234300000326F00000B71026E040043F60C166D0000000A4042725946

34574676716D00000028E7D8E44718236B0C17365E824FD3817ED2EF6C879FEE88D07EA92D030CEA72EE8E59309863128A3E"}

{"retcode":0,"result":"ok"}

需要把这个jsonUrlEncode一下再发送,否则会返回错误。

发送成功返回:{"retcode":0,"result":"ok"}

5。循环获取消息接口:

通过这个接口你可以实时的不间断的获取最新的消息。

/channel/poll?

clientid=15778909&psessionid=8368046764001D636F6E6E7365727665725F77656271714031302E3133332E332E3234300000326F00000B71026E040043F60C166D0000000A404272594634574676716D00000028E7D8E447182

36B0C17365E824FD3817ED2EF6C879FEE88D07EA92D030CEA72EE8E59309863128A3E&t=1288591644319

返回格式:

{"retcode":0,"result":[{"poll_type":"message","value":{"msg_id":9712,"from_uin":qq号码,"to_uin":qq号码,"msg_id2":217523,"msg_type":9,"reply_ip":2887452740,"time":1288591740,"content":[["font",{"size":9,"color":"000000","style":

[0,0,0],"name":"\u5B8B\u4F53"}],"helloworld"],"raw_content":"helloworld"}}]}

其中的poll_type表示消息格式,message就是普通的qq消息,可以看到发送人,发送时间,以及消息的内容等。

此接口很特殊,在实现时,需要循环不间断调用,如果没有消息返回,该接口会一直等待到,有消息,读取完后要立即再调用该接口。

6.其他接口

获取头像

/cgi/svr/face/getface?cache=0&type=1&fid=0&uin=号码

获取个人信息

/api/get_single_info?tuin=qq号码

获取签名

/api/get_single_long_nick?tuin=qq号码&t=1288751545148

获取好友列表

/api/get_user_friends

r

{"vfwebqq":"8f1383ba2239bb7295b100af215274aff1ee4be177b467cbc386fc53ff6606a8e5941aca61d0eb51"}

获取在线的qq好友

/channel/get_online_buddies?clientid=9547083&psessionid=8368046764001D636F6E6E7365727665725F77656271714031302E3133332E332E323430000062F000000B86026E040043F60C166D0000000A404F526B7558357668476D000000288F1383BA2239BB7295B100AF215274AFF1EE4BE177B467CBC386FC53FF6606A8E5941ACA61D0EB51&t=1288751548600

获取最近联系人

/api/get_recent_contact

r

{"vfwebqq":"8f1383ba2239bb7295b100af215274aff1ee4be177b467cbc386fc53ff6606a8e5941aca61d0eb51"}

等等。。。

7.附件这是本人通过java写的一个实例客户端,启动后,处于接受qq消息状态,当收到好友发来的消息时,回返回"然后呢?"。。。。

类似qq聊天机器人吧。。。

1.js是qq密码的加密js文件。

。。

完整代码:Java代码

import

java.awt.image.BufferedImage;

import

java.io.BufferedReader;

import

java.io.File;

import

java.io.FileReader;

import

java.io.InputStream;

import

java.io.InputStreamReader;

import

.HttpURLConnection;

import

.URL;

import

.URLEncoder;

import

java.util.Date;

import

java.util.Random;

import

java.util.regex.Matcher;

import

java.util.regex.Pattern;

import

javax.imageio.ImageIO;

import

javax.script.ScriptEngine;

import

javax.script.ScriptEngineManager;

import

atg.taglib.json.util.JSONArray;

import

atg.taglib.json.util.JSONException;

import

atg.taglib.json.util.JSONObject;

public

class

QQClient

{

private

int

qq

=

-1;

private

String

pwd

=

null;

private

int

clientid

=

66933334;//这个可以随便写

private

String

psessionid

=

"";

private

String

ptwebqq;

private

String

vfwebqq;

private

String

skey;

private

String

refer

=

"/proxy.html";

private

String

cookie

=

"";

//读取消息线程

private

boolean

isrun

=

false;

private

Thread

poolThread

=new

PollThread();

public

Thread

getPoolThread()

{

return

poolThread;

}

/**

*

记录日志

*/

private

void

log(String

msg){

System.out.println(new

Date().toLocaleString()+":"+msg);

}

public

QQClient(int

qq,

String

pwd)

{

this.qq

=

qq;

this.pwd

=

pwd;

try

{

boolean

rs

=

checkAndLogin();

if(rs){

isrun

=

true;

poolThread.start();//开始循环接收

log("启动成功");

}

}

catch

(Exception

e)

{

e.printStackTrace();

}

}

/*****************华丽的分界线*****************/

//测试

public

static

void

main(String[]

args)

throws

Exception{

QQClient

q

=

new

QQClient(qq号码,

"123");

q.getPoolThread().join();

}

/*****************华丽的分界线*****************/

/**

*

给toQQ发送一个msg消息,前提是toQQ是你的好友,要不然他收不到

*/

public

boolean

sendMsg(int

toQQ,

String

message){

try

{

JSONObject

json

=

new

JSONObject();

json.put("to",

toQQ);//要发送的人

json.put("face",

0);

JSONArray

msg

=

new

JSONArray();

msg.add(message);

JSONArray

font

=

new

JSONArray();

font.add("font");

JSONObject

font1

=

new

JSONObject().put("name",

"宋体").put("size",

"10");

JSONArray

style

=

new

JSONArray();

style.add(0);

style.add(0);

style.add(0);

font1.put("style",

style);

font1.put("color",

"000000");

font.add(font1);

msg.add(font);

json.put("content",

msg.toString());

json.put("msg_id",

new

Random().nextInt(10000000));

json.put("clientid",

clientid);

json.put("psessionid",

psessionid);//需要这个才能发送

String

sendMsgUrl

=

"/channel/send_msg";

String

content

=

json.toString();

content

=

URLEncoder.encode(content);//他要需要编码

content

="r="+content;

//发送

String

res

=

postUrl(sendMsgUrl,

content);

//不出意外,这是返回结果:{"retcode":0,"result":"ok"}

JSONObject

rh

=

new

JSONObject(res);

if("ok".equals(rh.getString("result"))){

return

true;

}

}

catch

(JSONException

e)

{

e.printStackTrace();

}

return

false;

}

/**

*

检查并且登陆

*/

private

boolean

checkAndLogin()

throws

Exception{

if(qq

==

-1

||

pwd

==

null)

throw

new

IllegalArgumentException("qq和密码不能为空");

String

checkIdUrl

=

"/check?appid=1003903&uin="+qq;

String

res

=

getUrl(checkIdUrl);

//ptui_checkVC('0','!ZLE');返回这个就不需要获取验证码了。验证码就是!ZLE

//ptui_checkVC('1','95ab7db15e5ab17f50f25d33598259e83ccc098c4af2f8a4');这个长字符串就需要使用了

Pattern

p

=

Pattern.

compile("\\,\\'([!\\w]+)\\'");

Matcher

m

=

p.

matcher(res);

String

checkType

=

"";

if(m.find()){

checkType

=

m.group(1);

}

String

check

=

"";

if(!checkType.startsWith("!")){

//需要输入验证码

String

getCheckImageUrl

=

"/getimage?aid=1003903&uin="+qq+"&vc_type="+checkType;

String

file

=

readCheckImage(getCheckImageUrl);

log("请打开"+file+",并且在这里输入其中的字符串,然后回车:");

InputStreamReader

ins

=

new

InputStreamReader(System.in);

BufferedReader

br

=

new

BufferedReader(ins);

check

=

br.readLine();

}else{

//不需要输入验证码

check

=

checkType;

}

//开始登陆

String

loginUrl

=

"/login?u="+qq+"&"

+

"p="

+mdP(pwd,

check)+

"&verifycode="+check+"&remember_uin=1&aid=1003903"

+

"&u1=http%3A%2F%2F%2Floginproxy.html%3Fstrong%3Dtrue"

+

"&h=1&ptredirect=0&ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert";

res

=

getUrl(loginUrl);

//

ptuiCB('0','0','/loginproxy.html?strong=true','0','登录成功!');

//

ptuiCB('4','0','','0','您输入的验证码有误,请重试。');

p

=

Ppile("登录成功!");//提取最后一个字符串,看看是不是

登录成功!

m

=

p.

matcher(res);

if(m.find()){

log("登陆成功");

}else{

//登陆失败

log(checkType);

return

false;

}

//从cookie中提取ptwebqq,skey

p

=

Ppile("ptwebqq=(\\w+);");

m

=

p.matcher(cookie);

if(m.find()){

ptwebqq

=

m.group(1);

}

p

=

Ppile("skey=(@\\w+);");

m

=

p.matcher(cookie);

if(m.find()){

skey

=

m.group(1);

}

log("ptwebqq="+ptwebqq+",skey="+skey);

//再次登陆,只有这次登陆,才算真正登陆qq,这个时候,如果你qq已经登陆,会把你的qq踢下线,而且此次登陆才算上线。

String

channelLoginUrl

=

"/channel/login";

String

content

=

"{\"status\":\"\",\"ptwebqq\":\""+ptwebqq+"\",\"passwd_sig\":\"\",\"clientid\":\""+clientid+"\"}";

content

=

URLEncoder.encode(content);//urlencode

content

=

"r="+content;//post的数据

res

=

postUrl(channelLoginUrl,

content);//post

//这次登陆基本上不会发生什么问题

//下面提取很重要的2个数据psessionid

,vwebqq,通用采用正则表达式,虽然结果是个json

p

=

Ppile("\"vfwebqq\":\"(\\w+)\"");

m

=

p.matcher(res);

if(m.find()){

vfwebqq

=

m.group(1);

}

p

=

Ppile("\"psessionid\":\"(\\w+)\"");

m

=

p.matcher(res);

if(m.find()){

psessionid

=

m.group(1);

}

log("vwebqq="+vfwebqq+","+"psessionid="+psessionid);

//到此,登陆就算完成了,后面可以调用发送qq信息等接口了

return

true;

}

/**

*

调用tx的js来生成密钥

*/

public

String

mdP(String

p,

String

code){

try

{

ScriptEngineManager

m

=

new

ScriptEngineManager();

ScriptEngine

se

=

m.getEngineByName("javascript");

se.eval(new

FileReader(new

File("1.js")));

Object

t

=

se.eval("md5(md5_3(\""+p+"\")+\""+code.toUpperCase()+"\");");

return

t.toString();

}catch

(Exception

e)

{

e.printStackTrace();

}

return

null;

}

/**

*

POST一个url,contents是输入的内容

*/

private

String

postUrl(String

url,

String

contents){

try{

System.out.println("post>>>"+url);

URL

serverUrl

=

new

URL(url);

HttpURLConnection

conn

=

(HttpURLConnection)

serverUrl.openConnection();

conn.setRequestMethod("POST");//"POST"

,"GET"

if(refer

!=

null){

conn.addRequestProperty("Referer",

refer);

}

conn.addRequestProperty("Cookie",

cookie);

conn.addRequestProperty("Accept-Charset",

"UTF-8;");//GB2312,

conn.addRequestProperty("User-Agent",

"Mozilla/5.0

(Windows;

U;

Windows

NT

5.1;

zh-CN;

rv:)

Firefox/3.6.8");

conn.setDoOutput(true);

conn.connect();

conn.getOutputStream().write(contents.getBytes());

if(conn.getHeaderFields().get("Set-Cookie")

!=

null){

for(String

s:conn.getHeaderFields().get("Set-Cookie")){

cookie

+=

s;

}

}

InputStream

ins

=

conn.getInputStream();

String

charset

=

"UTF-8";

InputStreamReader

inr

=

new

InputStreamReader(ins,

charset);

BufferedReader

bfr

=

new

BufferedReader(inr);

String

line

=

"";

StringBuffer

res

=

new

StringBuffer();

do{

res.append(line);

line

=

bfr.readLine();

//System.out.println(line);

}while(line

!=

null);

System.out.println(">>>==="+res);

return

res.toString();

}catch(Exception

e){

e.printStackTrace();

return

null;

}

}

/**

*

GET

一个url

*/

private

String

getUrl(String

url){

try{

System.out.println("get>>>"+url);

URL

serverUrl

=

new

URL(url);

HttpURLConnection

conn

=

(HttpURLConnection)

serverUrl.openConnection();

conn.setRequestMethod("GET");//"POST"

,"GET"

//

conn.setDoOutput(true);

if(refer

!=

null){

conn.addRequestProperty("Referer",

refer);

}

conn.addRequestProperty("Cookie",

cookie);

conn.addRequestProperty("Accept-Charset",

"UTF-8;");//GB2312,

conn.addRequestProperty("User-Agent",

"Mozilla/5.0

(Windows;

U;

Windows

NT

5.1;

zh-CN;

rv:)

Firefox/3.6.8");

conn.connect();

if(conn.getHeaderFields().get("Set-Cookie")

!=

null){

for(String

s:conn.getHeaderFields().get("Set-Cookie")){

cookie

+=

s;

}

}

InputStream

ins

=

conn.getInputStream();

String

charset

=

"UTF-8";

InputStreamReader

inr

=

new

InputStreamReader(ins,

charset);

BufferedReader

bfr

=

new

BufferedReader(inr);

String

line

=

"";

StringBuffer

res

=

new

StringBuffer();

do{

res.append(line);

line

=

bfr.readLine();

//System.out.println(line);

}while(line

!=

null);

System.out.println(">>>==="+res);

return

res.toString();

}catch(Exception

e){

e.printStackTrace();

return

null;

}

}

/**

*

读取验证码。返回验证码文件保存的路径

*/

private

String

readCheckImage(String

url){

try{

System.out.println("get>>>"+url);

URL

serverUrl

=

new

URL(url);

HttpURLConnection

conn

=

(HttpURLConnection)

serverUrl.openConnection();

conn.setRequestMethod("GET");//"POST"

,"GET"

conn.addRequestProperty("Accept-Charset",

"UTF-8;");//GB2312,

conn.addRequestProperty("User-Agent",

"Mozilla/5.0

(Windows;

U;

Windows

NT

5.1;

zh-CN;

rv:)

Firefox/3.6.8");

conn.connect();

//返回的cookie

if(conn.getHeaderFields().get("Set-Cookie")

!=

null)

for(String

s:conn.getHeaderFields().get("Set-Cookie")){

cookie

+=

s;

}

InputStream

ins

=

conn.getInputStream();

BufferedImage

bi

=

ImageIO.read(ins);

File

f

=new

File("qqimg.jpg");

ImageIO.write(bi,

"jpg",

f);

return

f.getAbsolutePath();

}catch(Exception

e){

e.printStackTrace();

}

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论