打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
用Java和Perl登录新浪微博
userphoto

2012.05.11

关注
By icycandy, at 2011/02/22 10:05:55
===============2011/06/28更新==========================
更新了HttpClient 4.x 模拟登录新浪微博的示例代码,经测试能正常登录,HttpClient 3.x和Perl版本的代码没有更新,有需要的同学自己参考HttpClient 4.x改写一下应该就可以了。希望大家也多一点探索精神,我没有精力经常来更新这个代码。
===============2011/05/24更新==========================
添加了用HttpClient 4.x 模拟登录新浪微博的示例代码
===============2011/05/22更新==========================
今天测试了日志中的Java代码,发现至少在目前是好用的,但是不保证以后会一直好用。感谢viLuo反馈的这个链接 新浪微博如何实现 SSO(t.sina.com.cn/weibo.com) 的分析,里面的内容写得很好很详细,遇到问题的同学可以去学习研究一下。
===============2011/03/29更新==========================
在最开始写这篇日志的时候,文中描述的两种方法的代码都经过了测试,能够成功登录。但是新浪的登录参数可能不停地在变化,所以如果你把日志中的代码直接复制回去,不能运行是很正常的情况。这里是文初写的模拟登录的一篇博客,里面涉及到了更多细节,有兴趣的朋友可以去看看。感谢zhaojiguang在评论中反馈此链接。
====================================================
现在新浪微博已经开放了API,为开发提供了很大的方便。但是仍然有一些事情是API所无能为力的,这时候就需要用到其他办法了。
1. 获得登录参数
一般的网站登录窗口都是一个简单的表单,随便搞一段代码就可以很轻易地登录上去,但是新浪的登录窗口却是由javascript控制的,稍微麻烦一些。对于简单的表单,可以通过查看html源代码获得登录参数;但是对于新浪这种,需要更深入一点的分析才行。
那么,要怎么办呢?答案是:万能的抓包工具。下面的截图分别展示了用Wireshark和Live HTTP headers(Firefox的一款插件)来获取登录参数的情况。
(1) Wireshark
抓包后找到带有 POST /sso/login.php?client=ssologin.js(v1.x.xx) HTTP/1.1的一行
然后右键,选择Follow TCP Stream,就会出来想要的结果,如图。注意看空行下面的红色文字部分。
(2) Live HTTP headers
实际上这个不算抓包工具,但是用起来更简单。注意看图中蓝底白字部分。
2. Java版
当获得了这些登录所需要传给服务器的参数以后,接下来的工作就比较简单了。
Java版主要用到了HttpClient,代码原始来源:http://flysnail.net/?p=27 ,我稍作了修改。
新浪微博中有一些页面登录前和登录后看到的内容不一样,比如 http://t.sina.com.cn/pub/tags ,程序中访问这个页面来检验是否登录成功。
(1) HttpClient 3.x版本
12345678910111213141516171819202122232425262728293031323334353637import java.io.IOException; import org.apache.commons.httpclient.HttpClient;import org.apache.commons.httpclient.HttpException;import org.apache.commons.httpclient.methods.GetMethod;import org.apache.commons.httpclient.methods.PostMethod; public class SinaLogin{ public static String login(String email, String passwd) throws HttpException, IOException { PostMethod post = new PostMethod("http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.11)"); post.addParameter("service", "miniblog"); post.addParameter("client", "ssologin.js(v1.3.11)"); post.addParameter("entry", "miniblog"); post.addParameter("encoding", "utf-8"); post.addParameter("gateway", "1"); post.addParameter("savestate", "7"); post.addParameter("from", ""); post.addParameter("useticket", "0"); post.addParameter("username", email); post.addParameter("password", passwd); post.addParameter("url", "http://t.sina.com.cn/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack"); post.addParameter("returntype", "META"); HttpClient client = new HttpClient(); client.executeMethod(post); GetMethod get = new GetMethod("http://t.sina.com.cn/pub/tags"); client.executeMethod(get); System.out.println(new String(get.getResponseBody())); return new String(get.getResponseBody()); }  public static void main(String[] args) throws HttpException, IOException { login("email","password"); }}
(2) HttpClient 4.x版本
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138package com.icycandy; import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern; import org.apache.commons.io.IOUtils;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.HttpClient;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.message.BasicNameValuePair; public class SinaLogin {  private final static HttpClient client = new DefaultHttpClient();  /** * 抓取网页 * * @param url * @throws IOException */ static String get(String url) throws IOException { HttpGet get = new HttpGet(url); HttpResponse response = client.execute(get); System.out.println(response.getStatusLine()); HttpEntity entity = response.getEntity();  String result = dump(entity); get.abort();  return result; }  /** * 执行登录过程 * * @param user * @param pwd * @param debug * @throws IOException */ static void login(String user, String pwd) throws IOException { HttpPost post = new HttpPost( "http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.14)"); post.setHeader("User-Agent", "Mozilla/5.0 (X11; Linux i686; rv:5.0) Gecko/20100101 Firefox/5.0"); post.setHeader("Referer", "http://weibo.com/"); post.setHeader("Content-Type", "application/x-www-form-urlencoded");  // 登录表单的信息 List<NameValuePair> qparams = new ArrayList<NameValuePair>(); qparams.add(new BasicNameValuePair("entry", "miniblog")); qparams.add(new BasicNameValuePair("gateway", "1")); qparams.add(new BasicNameValuePair("from", "")); qparams.add(new BasicNameValuePair("savestate", "0")); qparams.add(new BasicNameValuePair("useticket", "1")); qparams.add(new BasicNameValuePair("ssosimplelogin", "1")); qparams.add(new BasicNameValuePair("service", "miniblog")); // servertime=1309164392 // nonce=PJZCHM // qparams.add(new BasicNameValuePair("pwencode", "wsse")); qparams.add(new BasicNameValuePair("encoding", "utf-8")); qparams.add(new BasicNameValuePair( "url", "http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack")); qparams.add(new BasicNameValuePair("returntype", "META"));  qparams.add(new BasicNameValuePair("username", user)); qparams.add(new BasicNameValuePair("password", pwd));  UrlEncodedFormEntity params = new UrlEncodedFormEntity(qparams, "UTF-8"); post.setEntity(params);  // Execute the request HttpResponse response = client.execute(post); post.abort(); // 新浪微博登录没有301,302之类的跳转;而是返回200,然后用javascript实现的跳转 // int statusCode = response.getStatusLine().getStatusCode(); // if ((statusCode == HttpStatus.SC_MOVED_PERMANENTLY) // || (statusCode == HttpStatus.SC_MOVED_TEMPORARILY) // || (statusCode == HttpStatus.SC_SEE_OTHER) // || (statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) { // // 此处重定向处理 此处还未验证 // String newUri = response.getLastHeader("Location").getValue(); // get(newUri); // }  // Get hold of the response entity HttpEntity entity = response.getEntity(); // 取出跳转的url // location.replace("http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&ticket=ST-MTkxODMxOTI0Nw==-1309224549-xd-263902F174B27BAB9699691BA866EFF2&retcode=0"); String location = getRedirectLocation(dump(entity)); get(location); }  private static String getRedirectLocation(String content) { String regex = "location\\.replace\\(\'(.*?)\'\\)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(content);  String location = null; if (matcher.find()) { location = matcher.group(1); }  return location; }  /** * 打印页面 * * @param entity * @throws IOException */ private static String dump(HttpEntity entity) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader( entity.getContent(), "utf8"));  //return EntityUtils.toString(entity); return IOUtils.toString(br); }  public static void main(String[] args) throws IOException { login("username", "password"); String result = get("http://t.sina.com.cn/pub/tags"); System.out.println(result); }}
3. Perl版
Perl版代码是鑫哥给我的,未知原始来源,同样也稍作了修改
1234567891011121314151617181920212223242526272829303132333435use LWP::UserAgent;use HTTP::Cookies;use HTTP::Headers; my $ua = new LWP::UserAgent(keep_alive => 1);$ua->timeout(5);$ua->agent('Mozilla/4.0');$ua->cookie_jar(HTTP::Cookies->new(file=>'getsina.cookies',autosave=>1)); my $res = $ua->post('http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.11)', [ service => 'miniblog', client => 'ssologin.js(v1.3.11)', entry => 'miniblog', encoding => 'utf-8', gateway => '1', savestate => '7', username => 'username', password => 'password', from => '', useticket => '0', url => 'http://t.sina.com.cn/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack', returntype => 'META', ],);if (!$res->is_success) { print STDERR $res->status_line, "\n";} my $req = HTTP::Request->new(GET => 'http://t.sina.com.cn/pub/tags');$req->content_type('application/x-www-form-urlencoded');$res = $ua->request($req);print $res->as_string; exit(0);
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android Post Get(最新 HttpClient 事例)
HTTP
新浪微博模拟登录 java实现
[原]Java模拟新浪和腾迅自动登录并发送微博(2013年3月更新可用) | IT瘾
使用HttpClient通过POST方式发送XML
spring集成httpclient连接池配置
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服