java实现QQ空间模拟登录
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
import java.util.Scanner;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
public class QQLogin {
/*
http://ptlogin2.qq.com/login?....
模拟登录流程分析以及login接口重要参数分析:
【接口(重要参数) -> 返回的重要信息(说明)】
1、网上资料都说login_sig参数(来自xlogin接口)挺重要的,也许是tx改版了,个人亲测login_sig为空也行,连各个接口请求头的cookie都不需要设置。
2、需要注入的参数有:u,verifycode,pt_vcode_v1,pt_verifysession_v1,p。其他参数抓包时照搬就好。
3、u,p: Q号和加密过的密码。
4、pt_vcode_v1:此次登录是否需要验证码,不需要则为0,需要则为1,与check接口返回样例的第一个参数一致
5、verifycode:个人取它名为真实验证码,因为它不是手动输入的那个验证码。
6、pt_verifysession_v1:真实验证码对应的一个session值。
7、无需输入验证码时比较简单,verifycode,pt_verifysession_v1这两个参数直接能从check接口的responseBody中获取。
check(u) -> pt_vcode_v1(返回字符串中的第一个参数),verifycode(返回字符串中的第二个参数),pt_verifysession_v1(返回字符串中的第四个参数)
login(u,verifycode,pt_vcode_v1,pt_verifysession_v1,p) -> 登录成功cookie
8、需要输入验证码时复杂很多,因为上面那个两个参数并没有在check接口的返回值中给出,其中有用的是返回值中的第二个参数名为cap_cd。
check(u) -> cap_cd(返回字符串中的第二个参数)
cap_union_getsig_new(cap_cd) -> sig(响应体{"vsig":"SIG","ques":""})
getimgbysig(sig) -> ans(手动输入的验证码)
cap_union_verify(ans, sig) -> randstr(即login接口所需的verifycode参数), sig(即login接口所需的pt_verifysession_v1参数)
login(u,verifycode,pt_vcode_v1,pt_verifysession_v1,p) -> 登录成功cookie
9、若上述各个接口的参数没对上,常见的错误提示是验证码错误!
*/
/**
* qq空间模拟登录 main
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String uin = "2099221914";
String password = "zzjian";
String checkStatus = ""; //login接口参数pt_vcode_v1,对应check接口的0,1状态
String verifycode = ""; //login接口参数
String verifysession = ""; //login接口参数
String p = ""; //login接口参数
String checkResult = check(uin);
System.out.println(checkResult);
if("0".equals(checkResult.charAt(14)+"")) {
System.out.println("无需验证码登录!");
checkStatus = "0";
verifycode = checkResult.split(",")[1].replaceAll("\'", "");
verifysession = checkResult.split(",")[3].replaceAll("\'", "");
}
else {
System.out.println("需要输入验证码登录!。");
checkStatus = "1";
String cap_cd = checkResult.split(",")[1].replaceAll("'", "");
String sig = getSig(uin, cap_cd);
//获取并输入验证码
getVerifyCode(uin, sig);
System.out.println("请输入验证码:");
Scanner scanf = new Scanner(System.in);
String vcode = scanf.next(); //输入验证码
String body = getVerifysession(uin, vcode, sig);
verifysession = body.split(",")[2].replaceAll("sig:\"", "").replaceAll("\"", "");
verifycode = body.split(",")[1].replaceAll("randstr:\"", "").replaceAll("\"", "");
while(!body.contains("rcode:0")) {
sig = refreshSig(uin, sig);
getVerifyCode(uin, sig);
System.out.println("error,请重新输入验证码:");
vcode = scanf.next();
body = getVerifysession(uin, vcode, sig);
verifysession = body.split(",")[2].replaceAll("sig:\"", "").replaceAll("\"", "");
verifycode = body.split(",")[1].replaceAll("randstr:\"", "").replaceAll("\"", "");
}
}
p = encryptPassword(uin, password, verifycode);
String login_result = login1(uin, p, checkStatus, verifycode, verifysession);
System.out.println(login_result.split(",")[4]+","+login_result.split(",")[5]);
}
public static Map<String, String> cookies;
////////////////////////////////////////////////////////////////////////////////////////////
/* 不需验证码 begin */
/**
* 检查帐号状态(登录时是否需要验证码)。
* 若不需要,返回样例 ptui_checkVC('0','!GWD', '\x00\x....\x29','96b...5wf','0'),
* 样例说明:!GWD(真实验证码)为login接口的verifycode参数,'96b...5wf'为login接口的pt_verifysession_v1参数;
* 若需要,返回样例 ptui_checkVC('1','576429...df98', '\x00\x00...f1\x29','','0');
* 样例说明:'576429...df98'为cap_union_show接口的cap_cd参数
* @return
* @throws IOException
*/
public static String check(String uin) throws IOException {
Response response = Jsoup.connect("http://check.ptlogin2.qq.com/check?" +
"regmaster=" +
"&pt_tea=1" +
"&pt_vcode=1" +
"&uin=" + uin +
"&appid=549000912" +
"&js_ver=10140" +
"&js_type=1" +
"&login_sig=" +
"&u1=http%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone" +
"&r=0.6051186741306294")
.ignoreContentType(true)
.execute();
cookies = response.cookies();
return response.body();
}
/**
* 登录(第一次?)
* @return 登录成功时返回字符串:ptuiCB('0','0','http://web.qq.com/loginproxy.html?login2qq=1&webqq_type=10','0','登录成功','你的名字');
* @throws IOException
*/
public static String login1(String uin, String p, String checkStatus, String verifycode, String verifysession) throws IOException {
Response response = Jsoup.connect("http://ptlogin2.qq.com/login?" +
"u=" + uin +
"&verifycode=" + verifycode +
"&pt_vcode_v1=" + checkStatus +
"&pt_verifysession_v1=" + verifysession +
"&p="+p+
"&pt_randsalt=0" +
"&u1=http%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone" +
"&ptredirect=0" +
"&h=1" +
"&t=1" +
"&g=1" +
"&from_ui=1" +
"&ptlang=2052" +
"&action=2-1-1447938345482" +
"&js_ver=10140" +
"&js_type=1" +
"&login_sig=" +
"&pt_uistyle=32" +
"&aid=549000912" +
"&daid=5&")
.ignoreContentType(true)
.execute();
cookies.putAll(response.cookies());
return response.body();
}
/* 不需验证码 end */
/////////////////////////////////////////////////////////////////////////////////////////////
/**
* 返回值sig为getimgbysig接口(获取验证码接口)所需参数,
* 同时也是cap_union_verify接口(校验验证码正确性接口)所需参数。
* @param uin
* @param cap_cd
* @return
* @throws IOException
*/
public static String getSig(String uin, String cap_cd) throws IOException {
Response sigResponse = Jsoup.connect("http://captcha.qq.com/cap_union_getsig_new?" +
"clientype=2" +
"&captype=" +
"&protocol=http" +
"&disturblevel=" +
"&apptype=2" +
"&noBorder=noborder" +
"&showtype=embed" +
"&rnd=181847" +
"&aid=549000912" +
"&uin=" + uin +
"&cap_cd=" + cap_cd +//由check接口响应获得
"&rand=0.5029603082194563")
.execute();
String body = sigResponse.body();
String temp = body;
String beginString = "{\"vsig\":\"";
String sig = temp.substring(temp.indexOf(beginString)+beginString.length(), temp.indexOf("\",\""));
return sig;
}
/**
* 刷新sig,用来获取新的验证码图片
* @param oldSig
* @return 返回样例:cap_setQue("",0);cap_showOption(""); cap_getCapBySig("gOCP..m4-8CswYA**");
* @throws IOException
*/
public static String refreshSig(String uin, String oldSig) throws IOException {
Response response = Jsoup.connect("http://captcha.qq.com/getQueSig?" +
"aid=549000912" +
"&uin=" + uin +
"&captype=2" +
"&sig=" + oldSig +
"&0.6583711083512753")
.execute();
//截取结果中cap_getCapBySig("gOCP..m4-8CswYA**")引号部分
String newSig = response.body().split(";")[2].split("\"")[1];
return newSig;
}
/**
* 保存验证码图片
* @param
* @throws IOException
*/
public static void getVerifyCode(String uin, String sig) throws IOException {
Response imgResponse = Jsoup.connect("http://captcha.qq.com/getimgbysig?" +
"uin="+uin+
"&aid=549000912" +
"&sig="+sig)
.ignoreContentType(true)
.execute();
File imge = new File("resources/VerifyCode.jpg");
FileOutputStream out = new FileOutputStream(imge);
out.write(imgResponse.bodyAsBytes());
out.close();
}
/**
* 校验验证码正确性,返回结果包含rcode:0,则验证码输入正确
* @param uin
* @param verifycode 填写的验证码
* @param sig
* @return 正确时返回样例 : cap_InnerCBVerify({rcode:0,randstr:"@fmP",sig:"t02...aP12",errmsg:"..........................."})
* 从中获取 randstr:"@AIU"(真实验证码),以及sig:"..."(login接口所需的pt_verifysession_v1参数)。
* 验证码错误返回样例: cap_InnerCBVerify({rcode:5,randstr:"",sig:"",errmsg:"验证失败,请重试。"});
* @throws IOException
*/
public static String getVerifysession(String uin, String verifycode, String sig) throws IOException {
Response response = Jsoup.connect("http://captcha.qq.com/cap_union_verify?" +
"aid=549000912" +
"&uin=" + uin +
"&captype=50" +
"&ans=" + verifycode +
"&sig=" + sig +
"&0.49537746398709714")
.execute();
return response.body();
}
/**
* 密码加密,通过调用js函数加密
* @param verifycode 真实验证码,非手动输入的那个验证码
* @return 返回加密后的密码,login接口所需的p参数
*/
public static String encryptPassword(String uin, String password, String verifycode) {
String p_result = "";
try {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine engine = sem.getEngineByName("js");
FileReader fr = new FileReader("resources/login.js");
engine.eval(fr);
Invocable inv = (Invocable) engine;
p_result = inv.invokeFunction("getEncryption", password,
uin, verifycode).toString();
} catch (ScriptException e1) {
e1.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (FileNotFoundException e2) {
e2.printStackTrace();
}
return p_result;
}
/**
* 第二次登录
* @return
* @throws IOException
*/
public static String login2() throws IOException {
Response response = Jsoup.connect("")
.ignoreContentType(true)
.execute();
return response.body();
}
}
2016-11-27
代码中用到的模拟发请求的类库:http://files.cnblogs.com/files/zhangzongjian/jsoup.rar
代码中调用的js:http://files.cnblogs.com/files/zhangzongjian/login1.js
这个js是网上找来的,我也忘了是那个网站了。js是密码加密用的,是别人分析tx的js提取出来的精华,因为用tx的那个js文件用java自带的解析引擎解析语法报错。
java实现QQ空间模拟登录的更多相关文章
- Java版 QQ空间自动登录无需拷贝cookie一天抓取30WQQ说说数据&流程分析
QQ空间说说抓取难度比较大,花了一个星期才研究清楚! 代码请移步到GitHub GitHub地址:https://github.com/20100507/Qzone [没有加入多线程,希望你可以参与进 ...
- 1、IOS开发--iPad之仿制QQ空间(登录界面搭建+登录逻辑实现)
开始搭建登录界面 登录界面效果图: 相关的图片资源下载百度云备份链接: http://pan.baidu.com/s/1o71cvMU 密码: 2h7e 步骤开始: 设置辅助窗口的位置在下方 快捷键o ...
- Java豆瓣电影爬虫——模拟登录的前世今生与验证码的爱恨情仇
前言 并不是所有的网站都能够敞开心扉让你看个透彻,它们总要给你出些难题让你觉得有些东西是来之不易的,往往,这也更加激发你的激情和斗志! 从<为了媳妇的一张号,我与百度医生杠上了>里就有网友 ...
- JS/java实现QQ空间自动点赞
使用方法: 1:进入QQ空间 2:复制下面代码 3:按F12或右键审查元素 进入控制台 也就是console 4:粘贴 回车键 喝口水 5:如果嫌慢的话可以 修改这段代码. window.setI ...
- Python案例之QQ空间自动登录程序实现
不多说,直接上干货! 工具选择: 电脑系统:win7,32 位,下面第二部安装SetupTools时注意系统版本要求: Python: 2.7.11, 相信只要是2.7的就可以实现: Seleniu ...
- selenium模拟登录豆瓣和qq空间
selenium模拟登录豆瓣和qq空间今天又重新学习了下selenium,模拟登录豆瓣,发现设置等待时间真的是很重要的一步,不然一直报错:selenium.common.exceptions.NoSu ...
- 参数化登录QQ空间实例
通过参数化的方式,登录QQ空间 实例源码: # coding:utf-8 from selenium import webdriver import unittest import time clas ...
- QQ空间说说爬虫
QQ空间说说爬虫 闲来无事,写了一个QQ空间的爬虫,主要是爬取以前的说说,然后生成词云. 这次采用的主要模块是selenium,这是一个模拟浏览器的模块,一开始我不想用这个模块写的,但是后面分析的时候 ...
- QQ空间动态内容,好友信息,点赞爬虫脚本
一.安装基础的软件包: 1.准备好火狐浏览器,并下载geckodriver,将geckodriver加入到环境变量:下载geckodriver的地址:https://pan.baidu.com/s/1 ...
随机推荐
- swift 笔记 (十四) —— 构造过程
构造过程 为了生成类.结构体.枚举等的实例,而做的准备过程,叫做构造过程. 为了这个过程,我们一般会定义一个方法来完毕,这种方法叫做构造器.当然它的逆过程,叫做析构器,用于在实例被释放前做一些清理工作 ...
- Java设计模式菜鸟系列(十五)建造者模式建模与实现
转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39863125 建造者模式(Builder):工厂类模式提供的是创建单个类的模式.而建造者模 ...
- ORACLE 树形查询 树查询
前台树结构依据个人的权限登录变化 全部我查询要依据 树的ID 查询以下全部的子节点 以及本节点的信息 select * from table start with id = #{id} connect ...
- ZOJ 1649 Rescue(有敌人迷宫BFS)
题意 求迷宫中从a的位置到r的位置须要的最少时间 经过'.'方格须要1s 经过'x'方格须要两秒 '#'表示墙 因为有1s和2s两种情况 须要在基础迷宫bfs上加些推断 令到达每一个点的时间初 ...
- leetcode解题文件夹
点击打开链接点击打开链接点击打开链接參考文献:http://blog.csdn.net/lanxu_yy/article/details/17848219 只是本文准备用超链接的方式连接到对应解答页面 ...
- 黑马day01xml 解析方式与原理分析
dom解析方式和sax解析
- 常用框架(一):spring+springMvc+mybatis+maven
项目说明: (1) 本例采用 maven web 工程做例子讲解 (2) 利用mybaits 提供的代码生成工具自动生成代码(dao接口,sql mapper映射文件,pojo数据库映射类) (3) ...
- Linux - 设置光盘,开机自动挂载。
设置光盘,开机自动挂载. 挂载, 在linux操作系统中, 挂载是指将一个设备(通常是存储设备)挂接到一个已存在的目录上. 我们要访问存储设备中的文件,必须将文件所在的分区挂载到一个已存在的目录上, ...
- 软件-集成开发环境:IDE
ylbtech-软件-集成开发环境:IDE 集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器.编译器. ...
- 用虚拟机创建win7 32位系统来测试win 7 64位系统无法安装cad 2004 缺少acdb16.dll的问题