[原]Java模拟新浪和腾迅自动登录并发送微博(2013年3月更新可用)
标签:
| 发表时间:2013-03-14 08:47 | 作者:supercrsky 分享到:
出处:http://blog.csdn.net/supercrsky1.准备工作 只是登录无需申请新浪和腾迅的开发者账号,如果需要发送微博功能,需要申请一个新浪和腾迅的开发者账号,并添加一个测试应用。 过程请参考官方帮助文档,申请地址:新浪:http://open.weibo.com 腾迅:http://dev.t.qq.com/ 我们需要的是App Key和App Secre及redirect_URI,源代码中已经包含了我申请的测试key,但由于限制直接用我的key你们的账号是无法登录成功的。 2.注意事项 1)需要注意的是应用的App Key和App Secre及redirect_URI,对应项目根目录下的config.properties配置文件中的 client_ID=1745656892 client_SERCRET=66056719c1d8ca7bcaf36f411217cefa redirect_URI=www.baidu.com redirect_URI由于只是测试用并没有直接的回调页面,所以这里随便填写一个地址就行了,但要注意与应用-高级设置里的“回调页面”一致。 2)代码中的测试账号需要要自己添加测试账号,新浪的在“应用信息-测试账号”;腾迅的在“权限控制-创建白名单”中。当然直接用 开发者账号也可以。 3)发送微博引用了新浪的 weibo4j-oauth2-beta2.1.1.zip,腾迅的 Java_SDK_v1.2.1.7z。核心类在util包下。 3.关键代码 1)新浪
package org.utils; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.http.HttpException; import org.core.weibo.sina.Oauth; import org.core.weibo.sina.Timeline; import org.core.weibo.sina.http.AccessToken; import org.core.weibo.sina.model.WeiboException; import org.core.weibo.sina.weibo4j.util.WeiboConfig; /*** * 模拟自动登录并发微博 * @author zdw * */ public class Sina { /*** * 模拟登录并得到登录后的Token * @param username 用户名 * @param password 密码 * @return * @throws HttpException * @throws IOException */ public static AccessToken getToken(String username,String password) throws HttpException, IOException { String clientId = WeiboConfig.getValue("client_ID") ; String redirectURI = WeiboConfig.getValue("redirect_URI") ; String url = WeiboConfig.getValue("authorizeURL"); PostMethod postMethod = new PostMethod(url); //应用的App Key postMethod.addParameter("client_id",clientId); //应用的重定向页面 postMethod.addParameter("redirect_uri",redirectURI); //模拟登录参数 //开发者或测试账号的用户名和密码 postMethod.addParameter("userId", username); postMethod.addParameter("passwd", password); postMethod.addParameter("isLoginSina", "0"); postMethod.addParameter("action", "submit"); postMethod.addParameter("response_type","code"); HttpMethodParams param = postMethod.getParams(); param.setContentCharset("UTF-8"); //添加头信息 List<Header> headers = new ArrayList<Header>(); headers.add(new Header("Referer", "https://api.weibo.com/oauth2/authorize?client_id="+clientId+"&redirect_uri="+redirectURI+"&from=sina&response_type=code")); headers.add(new Header("Host", "api.weibo.com")); headers.add(new Header("User-Agent","Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0")); HttpClient client = new HttpClient(); client.getHostConfiguration().getParams().setParameter("http.default-headers", headers); client.executeMethod(postMethod); int status = postMethod.getStatusCode(); System.out.println(status); if (status != 302) { System.out.println("token刷新失败"); return null; } //解析Token Header location = postMethod.getResponseHeader("Location"); if (location != null) { String retUrl = location.getValue(); int begin = retUrl.indexOf("code="); if (begin != -1) { int end = retUrl.indexOf("&", begin); if (end == -1) end = retUrl.length(); String code = retUrl.substring(begin + 5, end); if (code != null) { Oauth oauth = new Oauth(); try{ AccessToken token = oauth.getAccessTokenByCode(code); return token; }catch(Exception e){ e.printStackTrace(); } } } } return null; } /** * 发微博 * @param token 认证Token * @param content 微博内容 * @return * @throws Exception */ public static boolean sinaSendWeibo(String token,String content) throws Exception { boolean flag = false ; Timeline timeline = new Timeline(); timeline.client.setToken(token); try { timeline.UpdateStatus(content); flag = true ; } catch (WeiboException e) { flag = false ; System.out.println(e.getErrorCode()); } return flag; } public static void main(String[] args) throws Exception { AccessToken at = getToken("xxxx","xxx"); sinaSendWeibo(at.getAccessToken(),"测试呢"); } } 腾迅: package org.utils; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.util.Scanner; import net.sf.json.JSONObject; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.core.weibo.tencent.api.UserAPI; import org.core.weibo.tencent.oauthv2.OAuthV2; import org.core.weibo.tencent.oauthv2.OAuthV2Client; /*** * 腾迅自动登录并获取个人信息 * @author zdw * */ public class Tencent { public static final String HEXSTRING = "0123456789ABCDEF"; public static OAuthV2 oAuth = new OAuthV2(); private static HttpClient client = new DefaultHttpClient(); // 初始oAuth应用信息 public static void init(OAuthV2 oAuth) { oAuth.setClientId("801216331"); oAuth.setClientSecret("ea71b26b0cbe5778cdd1c09ad17553a3"); oAuth.setRedirectUri("http://www.tencent.com/zh-cn/index.shtml"); } /** * * @param qq * http://check.ptlogin2.qq.com/check?uin={0}&appid=15000101&r={1 } * 返回的第三个值 * @param password * QQ密码 * @param verifycode * 验证码 * @return 加密后的密码 * @throws UnsupportedEncodingException * @throws Exception * */ public static String GetPassword(String qq, String password, String verifycode) throws Exception { String P = hexchar2bin(md5(password)); String U = md5(P + hexchar2bin(qq.replace("\\x", "").toUpperCase())); String V = md5(U + verifycode.toUpperCase()); return V; } public static String md5(String originalText) throws Exception { byte buf[] = originalText.getBytes("ISO-8859-1"); StringBuffer hexString = new StringBuffer(); String result = ""; String digit = ""; try { MessageDigest algorithm = MessageDigest.getInstance("MD5"); algorithm.reset(); algorithm.update(buf); byte[] digest = algorithm.digest(); for (int i = 0; i < digest.length; i++) { digit = Integer.toHexString(0xFF & digest[i]); if (digit.length() == 1) { digit = "0" + digit; } hexString.append(digit); } result = hexString.toString(); } catch (Exception ex) { result = ""; } return result.toUpperCase(); } public static String hexchar2bin(String md5str) throws UnsupportedEncodingException { ByteArrayOutputStream baos = new ByteArrayOutputStream(md5str.length() / 2); for (int i = 0; i < md5str.length(); i = i + 2) { baos.write((HEXSTRING.indexOf(md5str.charAt(i)) << 4 | HEXSTRING .indexOf(md5str.charAt(i + 1)))); } return new String(baos.toByteArray(), "ISO-8859-1"); } /*** * 模拟登录 * @param qq QQ号码 * @param password QQ密码 * @throws Exception */ public static void login(String qq, String password) throws Exception { HttpGet get = new HttpGet("https://ssl.ptlogin2.qq.com/check?uin="+ qq + "&appid=46000101&ptlang=2052&js_type=2&js_ver=10009&r=0.7948186025712065"); HttpResponse response = client.execute(get); String entity = EntityUtils.toString(response.getEntity()); String[] checkNum = entity.substring(entity.indexOf("(") + 1,entity.lastIndexOf(")")).replace("'", "").split(","); String pass = ""; String responseData = ""; // 获取验证码(如果有验证码输出到C:/code.jpg,查看后输入可继续执行 if ("1".equals(checkNum[0])) { // uin为qq号或者微博用户名 HttpGet getimg = new HttpGet("http://captcha.qq.com/getimage?aid=46000101&r=0.3478789969909082&uin=" + qq + "&vc_type=" + checkNum[1] + ""); HttpResponse response2 = client.execute(getimg); OutputStream os = new FileOutputStream("c:/code.jpg"); byte[] b = EntityUtils.toByteArray(response2.getEntity()); os.write(b, 0, b.length); os.close(); Scanner in = new Scanner(System.in); responseData = in.nextLine(); in.close(); } else { responseData = checkNum[1]; } /** *******************加密密码 ************************** */ pass = GetPassword(checkNum[2], password, responseData); /** *********************** 登录 *************************** */ HttpGet getimg = new HttpGet("https://ssl.ptlogin2.qq.com/login?ptlang=2052&u="+ qq+ "&p="+ pass+ "&verifycode="+ responseData+ "&aid=46000101&target=top&u1=https%3A%2F%2Fopen.t.qq.com%2Fcgi-bin%2Foauth2%2Fauthorize%3Fclient_id%3D" + oAuth.getClientId()+ "%26response_type%3Dcode%26redirect_uri="+ oAuth.getRedirectUri()+ "&ptredirect=1&h=1&from_ui=1&dumy=&qlogin_param=abbfew=ddd&wording=%E6%8E%88%E6%9D%83&fp=loginerroralert&action=8-13-240977&g=1&t=1&dummy=&js_type=2&js_ver=10009"); HttpResponse response2 = client.execute(getimg); HttpEntity httpentity = response2.getEntity(); String entityxc = EntityUtils.toString(httpentity); System.out.println(entityxc); } /** * * 请求微博开放平台应用 返回登录授权页面,但是如果没有sessionKey的话永远登录不成功 sessionKey * 发现在返回的页面中一个input标签里放的url中有,所以要取到这个sessionKey 其实直接访问标签中的url就可以跳转 * */ public static String getUrl() throws ClientProtocolException, IOException { HttpGet getcode = new HttpGet("https://open.t.qq.com/cgi-bin/oauth2/authorize?client_id="+ oAuth.getClientId()+ "&response_type=code&redirect_uri=" + oAuth.getRedirectUri()+ "&checkStatus=yes&appfrom=&g_tk&checkType=showAuth&state="); HttpResponse response3 = client.execute(getcode); HttpEntity entityqqq = response3.getEntity(); String entityxcc = EntityUtils.toString(entityqqq); String form = entityxcc.substring(entityxcc.indexOf("<form"), entityxcc .indexOf("</form>")); String[] ss = form.split("/>"); String input = ""; for (int i = 0; i < ss.length; i++) { if (ss[i].indexOf("name=\"u1\"") > 0) { input = ss[i]; } ; } return input.substring(input.indexOf("value=\"") + 7, input.indexOf("\" type=\"")); } /** * 解析并设置Token * @param get * @throws Exception */ public static void setToken(HttpGet get) throws Exception { HttpResponse response4 = client.execute(get); HttpEntity entityqqq1 = response4.getEntity(); String getUrlcode = EntityUtils.toString(entityqqq1); // 返回了最终跳转的页面URL,也就是回调页redirect_uri,页面地址上包含code openid openkey // 需要将这三个值单独取出来再拼接成 code=xxxxx&openid=xxxxx&openkey=xxxxxx的形式 String entity = getUrlcode.substring(getUrlcode.indexOf("url="),getUrlcode.indexOf("\">")); StringBuffer sb = new StringBuffer(); String[] arr = entity.split("\\?")[1].split("&"); for (int x = 0; x < arr.length; x++) { if (arr[x].indexOf("code") >= 0 || arr[x].indexOf("openid") >= 0 || arr[x].indexOf("openkey") >= 0) { sb.append(arr[x] + "&"); } ; } // 利用code获取accessToken OAuthV2Client.parseAuthorization(sb.substring(0, sb.length() - 1), oAuth); oAuth.setGrantType("authorize_code"); OAuthV2Client.accessToken(oAuth); } /*** * 调用(腾迅开放平台账户接口)获取一个人的信息 * @throws Exception */ public static void getInfo() throws Exception { //输出Token,如果拿到了Token就代表登录成功,并可以进行下一步操作。 System.out.println("Token="+oAuth.getAccessToken()); UserAPI getuser = new UserAPI(oAuth.getOauthVersion()); String userJson = getuser.otherInfo(oAuth, "json", "", oAuth.getOpenid()); JSONObject userJsonObject = JSONObject.fromObject(userJson); Integer errcode = (Integer) userJsonObject.get("errcode"); if (errcode == 0) { JSONObject userdataJsonObject = (JSONObject) userJsonObject.get("data"); System.out.println(userdataJsonObject.toString()); } } public static void main(String[] args) throws Exception { init(oAuth); login("123145", "xxxx"); HttpGet get = new HttpGet(getUrl()); setToken(get); getInfo(); } } 4.发送成功都有对应的日志输出 新浪(最后一行日志):
2078 DEBUG [2013-03-14 16:35:29] {"created_at":"Thu Mar 14 16:35:30 +0800 2013","id":3555791132949940,"mid":"3555791132949940","idstr":"3555791132949940","text":"测试呢","source":"... 腾迅: 登录成功的日志标志:
ptuiCB('0','0','https://open.t.qq.com/cgi-bin/oauth2/authorize?client_id=801216331&response_type=code&redirect_uri=http:','1','登录成功!', 'ㄗs:ヤ淡 啶');查看个人信息成功后的日志标志:
QHttpClient httpGet [3] Response = {"data":{"birth_day":26,"birth_month":8,"birth_year":2011,"city_code":"2","comp":null,"country_code":"1","edu":null,"email":"","exp":141,"fansnum":.. 日志未全列出,只是作为参考。
作者:supercrsky 发表于2013-3-14 16:47:53 原文链接
阅读:106 评论:1 查看评论
相关 [java 模拟 新浪] 推荐:[原]Java模拟新浪和腾迅自动登录并发送微博(2013年3月更新可用)- - 上善若水 厚德载物 只是登录无需申请新浪和腾迅的开发者账号,如果需要发送微博功能,需要申请一个新浪和腾迅的开发者账号,并添加一个测试应用. 过程请参考官方帮助文档,申请地址:新浪:http://open.weibo.com 腾迅:http://dev.t.qq.com/. 我们需要的是App Key和App Secre及redirect_URI,源代码中已经包含了我申请的测试key,但由于限制直接用我的key你们的账号是无法登录成功的. 1)需要注意的是应用的App Key和App Secre及redirect_URI,对应项目根目录下的config.properties配置文件中的. redirect_URI由于只是测试用并没有直接的回调页面,所以这里随便填写一个地址就行了,但要注意与应用-高级设置里的“回调页面”一致. HttpClient 模拟登录Web版新浪微博- - zzm其中密码部分进行了加密,加密的算法在网页的js文件里,网上有人把它改成了Java代码. 下面是SinaSSoEncoder类:. m += k.charAt((l[j >> 2] >> ((3 - j % 4) * 8 + 4)) & 15) + "". B[l] = d(B[l - 3] ^ B[l - 8] ^ B[l - 14] ^ B[l - 16], 1);. int C = e(e(d(z, 5), a(l, y, v, u)), e(e(s, B[l]), c(l)));. 转:http://www.cnblogs.com/e241138/archive/2012/09/16/2687124.html. HttpClient 模拟登录手机版新浪微博- - zzm我们要做的就是获取服务器需要的数据,然后用HttpClient模拟浏览器提交. go标签内的href是我们第二次请求的地址,通过这个地址来获取cookie. 用户密码那个field的name属性是随机变化的,需要先获取它然后提交. 思路:先获取表单的值,然后用POST方法提交. 注意添加RequestHeader信息,否则会被服务器拒绝(403). * 获取手机版微博的cookies. 如果用户名密码正确的话,应该就可以获得cookie了. 接下来如果想要访问某些网页只需要带上cookie就行了. 由于新浪的网页可能会变化,所以不保证此方法一直能用,不过大体思路应该是不会变的. 转:http://www.cnblogs.com/e241138/archive/2012/09/16/2687120.html. java模拟浏览器包htmlunit,selenium- - BlogJava-首页技术区发现一个很不错的模拟浏览器包htmlunit,它可以直接执行访问网站地址,并执行相应的JavaScript脚本;这个功能对于网站爬虫有很大的帮助,一些网站使用了ajax,如果使用简单的http访问只能抓到原始的html源码,但对于页面内执行的ajax却无法获取;使用这个包后,可以将执行ajax后的html源码一并抓取下来. 网站地址:http://htmlunit./. 该站点下边还提到了几个相类似的包:HtmlUnit is used as the underlying "browser" by different Open Source tools like Canoo WebTest,. 新浪微游戏首现独立的HTML5模拟经营类游戏《疯狂老板》- - HTML5研究小组微游戏是基于新浪微博平台的好友关系及互动而推出的一系列游戏. 目前微游戏中基本都是Flash游戏为主,而鲜少有真正更适合微博平台的随时随地性的HTML5游戏. 2011年8月,《愤怒的小鸟》开发商Rovio首先开发出该游戏的HTML5版. 随后,社交游戏巨头Zynga也发布了三款适用于苹果产品的HTML5游戏. Facebook的移动HTML5游戏平台斯巴达计划也已被曝光. 而国内HTML5游戏才刚刚起步,微游戏亦是如此,直到今年的2月21日,微游戏平台第一个独立的HTML5模拟经营类社交游戏《疯狂老板》才上线. 这款全新的HTML5游戏在讨论区的公告如下:《疯狂老板》是全新原创在电脑、平板电脑、手机都可通用的跨终端平台游戏,由新浪微游戏首发,而且只是在新浪一个平台上发布,主题是创建公司当自己当老板的公司经营类游戏. JavaScript PC 模拟器- kira - LinuxTOY很难想象竟然用了这么久,Linux 才可以运行在浏览器的 JavaScript 引擎里面,要知道2008 年就可以在土豆上运行了~. 作者 Fabrice Bellard 使用 JavaScript 编写了一个简单的 PC 模拟器,包含32位 x86 兼容 CPU、8259 可编程中断控制器、8254 可编程中断计时器. 实现 16450 UART 串口设备. 用 JavaScript 实现一个终端. 编译包含 FPU 模拟的 Linux 内核镜像. 使用 Buildroot 创建文件系统并在启动时载入 RAM. 添加基本工具集 BusyBox,微型 C 编译器 TinyCC,以及迷你编辑器 QEmacs. 根据新浪天气API获取各地天气状况(Java实现)- - CSDN博客互联网推荐文章http://blog.csdn.net/cyxlzzs/article/details/7602469 新浪. http://blog.csdn.net/l_ch_g/article/details/8205817 新浪. http://blog.csdn.net/killtl/article/details/7312514 新浪. http://blog.csdn.net/qq910894904/article/details/7540093 新浪. http://blog.sina.com.cn/s/blog_417845750101d5ws.html 国家气象局. http://www./demo_c131_i42456.html 国家气象局. JavaScript Gameboy Color模拟器- ashuai - Solidot程序员Grant Galitz发布了一个用HTML5/JavaScript编写的GameBoy Color模拟器(源代码),可以运行储存在本地的ROM镜像,游戏运行速度正常. 也有其他开发者用JavaScript编写出了启动Linux的X86模拟器. 地形模拟演示Demo- kongshanzhanglao - 博客园-首页原创精华区地形渲染的首先是创建一个三角网络平面,然后调整平面顶点的y高度值,模拟地面的山丘和山谷,最后再绘制贴图效果. 本文首先介绍如何生成三角网络平面. 然后介绍如何通过高度图调整平面高度. 以及使用BlendMap和3种材质绘制贴图效果的方法. 最后演示如何调整摄像机位置和移动速度,在地面上行走. 一个m*n个顶点的平面由2*(m-1)*(n-1)个三角形组成. 首先生成顶点坐标,假设平面的中心在坐标原点. 左上角的顶点坐标就为(-(m-1)*dx, 0, (n-1)*dz). 再生成索引,每个循环迭代中生成一个四边形的两个三角形的6个索引信息. 然后使用生成的顶点坐标和索引创建ID3DXMesh对象. 模拟银河系的演化- Yan - Solidot加州大学Santa Cruz分校和瑞士苏黎世理论物理研究院科的科学家利用NASA的Pleiades超级计算机,历时9个月时间的运算,模拟了星系的起源和演化. 预印本发表在arXiv.org上. 他们所模拟的星系称为Eris. 研究小组首先从低分辨率开始,模拟最初的暗物质演化成一个类银河星系的控制中心,然后放大中心光环区,引入气体粒子并大幅度提高分辨率,再追踪粒子间的相互作用的演化. |
|