httpclient 登录人人,并且发表说说。
(大家有什么意见或者,更好的学习方式,解决问题的方法欢迎提出,小弟好改进)
前段时间,感觉模拟登录人人挺有意思的。
代码调用的是叫做httpclient相关的包,随后便下载中文文档打印出来,开始全方位看文档。看不懂不理解,只知道它是模拟的浏览器,然后我就想浏览器的工作过程?
解决方法:网上较多的说的是http协议,我就开始看http协议,http协议中各种信息传递的方法,但是不理解啊,感觉越来越虚和我模拟登录的初衷越走越远,突然发现了抓包分析软件可以让我真切的了解登录过程,第一个抓包软件用的是浏览器自带的,跟着别人博客的走一遍,然后就开始抓人人登录过程,一遍又一遍的抓取,逐渐记住了抓包的http消息头中的参数,http协议理解越来越深刻了,这时候又开始看httpclient的文档,数据的传输格式神马的又让我开始蛋疼,而且传过去后服务器如何获取,如何处理让我也很难受,所以我就花了一天搭建了一个php后台运行环境,写了点后台运行的php代码,同时写了几个jsp代码,终于对数据的传输有基本的认识,同时开始敲代码,找博客,看文档,最后在成功的时候感觉这段时间没白费。
下面我贴出我的代码:本来还想扩充抓人人中的好友信息,但是人人已经有了隐私保护机制,好多人的东西获取不到,所以我刚开始设置了两个类,一个主类(main)负责调用功能,一个负责实现功能(Login)。
1.主类
import java.io.IOException; import java.util.Scanner; import org.apache.http.ParseException; public class Main { /** * @param args * @throws IOException * @throws ParseException * @throws IOException * @throws ParseException */ public static void main(String[] args) throws ParseException, IOException { // TODO Auto-generated method stub Login login = new Login(); System.out.println("请输入要留言的消息:"); String message = new Scanner(System.in).nextLine(); login.leaveMessage(message); // login.getFriend(); } }
2.功能实现类
import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.Scanner; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; 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.BasicResponseHandler; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; public class Login { // 创建一个浏览器 static DefaultHttpClient httpClient; static String content; static String hostid; static String requestToken; // static String privacyParams; static String _rtk; Login() throws ParseException, IOException { httpClient = new DefaultHttpClient(); String origURL = "http://www.renren.com/home"; String domain = "renren.com"; String loginURL = "http://www.renren.com/PLogin.do"; String email; String passWord; System.out.println("请输入帐号:"); email = new Scanner(System.in).nextLine(); System.out.println("请输入密码:"); passWord = new Scanner(System.in).nextLine(); // 以post方式请求目标页面 HttpPost httpPost = new HttpPost(loginURL); System.out.println("aaaaa"); // 填写http请求head内容 List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("email", email)); params.add(new BasicNameValuePair("key_id", "1")); params.add(new BasicNameValuePair("password", passWord)); params.add(new BasicNameValuePair("origURL", origURL)); params.add(new BasicNameValuePair("domain", domain)); params.add(new BasicNameValuePair("icode", "")); params.add(new BasicNameValuePair("captcha_type", "web_login")); try { // 网页是编码方式是utf-8 所以先要把传递参数设置为utf-8 httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } // 调用postMethod函数处理请求response HttpResponse response = postMethod(httpPost); System.out.println(response.getStatusLine().getStatusCode()); // 抓包发现页面返回了302跳转,获取跳转后的页面,页面跳转由浏览器执行。 String url = response.getFirstHeader("Location").getValue(); // 获得返回的html String content = getContent(url); // 获取响应实体 // HttpEntity entity = response.getEntity(); // 获取返回的html // String content = EntityUtils.toString(entity); // http头是以ISO-8859-1格式传递的 // content = new String(content.getBytes("ISO-8859-1"),"UTF-8"); int hostidBeginIndex = content.indexOf("&hostid="); int hostidEndIndex = content.indexOf("&callback"); hostid = content.substring(hostidBeginIndex + 8, hostidEndIndex); System.out.println(hostid); int rtkBeginIndex = content.indexOf("get_check_x:'"); int rtkEndIndex = content.indexOf("',env:"); _rtk = content.substring(rtkBeginIndex + 13, rtkEndIndex); System.out.println(_rtk); int requestTokenBeginIndex = content.indexOf("get_check:'"); int requestTokenEndIndex = content.indexOf("',get_check_x"); requestToken = content.substring(requestTokenBeginIndex + 11, requestTokenEndIndex); System.out.println(requestToken); } public HttpResponse postMethod(HttpPost httpPost) { HttpResponse httpResponse = null; try { // 执行请求并且返回结果 httpResponse = httpClient.execute(httpPost); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 释放系统资源 httpPost.abort(); } return httpResponse; } public String getContent(String url) { // 创建get 方法 HttpGet httpGet = new HttpGet(url); // 创建字符串 ResponseHandler ResponseHandler<String> responseHandler = new BasicResponseHandler(); String content = null; try { // 执行get方法 content = httpClient.execute(httpGet, responseHandler); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 释放get方法的资源 httpGet.abort(); } return content; } public void leaveMessage(String message) throws UnsupportedEncodingException { String postUrl = "http://shell.renren.com" + "/" + hostid + "/status"; HttpPost httpPost = new HttpPost(postUrl); List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("content", message)); params.add(new BasicNameValuePair("hostid", hostid)); params.add(new BasicNameValuePair("requestToken", requestToken)); params.add(new BasicNameValuePair("_rtk", _rtk)); params.add(new BasicNameValuePair("channel", "renren")); httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); postMethod(httpPost); } public void getFriend() { String html = getContent("http://friend.renren.com/GetFriendList.do?curpage=1&id=247600428"); System.out.println(html); } }
代码中注释比较多,我就不再说什么了,发表日志分享日志只是简单的重复post过程和get的过程我就没写了。
后续我想写一个抓取博客园关系网的东西,使其可视化,如果大家谁有资料可以推荐下。
我将记录我如何从一点都不懂到懂的过程,一是想看看自己解决问题中如何实现逻辑化,二是让下次遇到问题更加思维清晰的去解决。