登录的站点是3g.renren.com 因为是手机人人, 页面比较简单

首先用HttpGet取出"http://3g.renren.com"的html代码, 是用Jsoup解析出登录表单, 包括验证码的图片的url

因为没法做到绕过验证码,所以用验证码的url构建一个image, 显示出来让用户自己填写

构建image时一定要用httpget, 开始使用了ImageIO.read(new URL(url)); 这样, HttpClient实例中没有管理session

不写了, 全放到注释里去了, 直接上代码

因为程序很依赖html源码, 哪天人人的前台改动了html代码说不定就用不了了

  1. package com.renren.main;
  2. import java.awt.Graphics;
  3. import java.awt.Image;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.awt.image.BufferedImage;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.util.ArrayList;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. import javax.imageio.ImageIO;
  14. import javax.swing.JButton;
  15. import javax.swing.JFrame;
  16. import javax.swing.JPanel;
  17. import javax.swing.JPasswordField;
  18. import javax.swing.JTextArea;
  19. import javax.swing.JTextField;
  20. import org.apache.http.HttpEntity;
  21. import org.apache.http.HttpResponse;
  22. import org.apache.http.HttpStatus;
  23. import org.apache.http.NameValuePair;
  24. import org.apache.http.client.ClientProtocolException;
  25. import org.apache.http.client.HttpClient;
  26. import org.apache.http.client.ResponseHandler;
  27. import org.apache.http.client.entity.UrlEncodedFormEntity;
  28. import org.apache.http.client.methods.HttpGet;
  29. import org.apache.http.client.methods.HttpPost;
  30. import org.apache.http.impl.client.BasicResponseHandler;
  31. import org.apache.http.impl.client.DefaultHttpClient;
  32. import org.apache.http.message.BasicNameValuePair;
  33. import org.apache.http.protocol.HTTP;
  34. import org.jsoup.Jsoup;
  35. import org.jsoup.nodes.Document;
  36. import org.jsoup.nodes.Element;
  37. import org.jsoup.select.Elements;
  38. public class Login extends JFrame implements ActionListener{
  39. private JTextField email;
  40. private JPasswordField password;
  41. private JTextField verifycode;
  42. private JButton login;
  43. private ImageBoxPanel imageBox;
  44. private Image image;
  45. private MsgBox box;
  46. private final HttpClient client;
  47. private HttpPost post;
  48. private HttpGet get;
  49. private HttpResponse response;
  50. private ResponseHandler<String> responseHandler;
  51. private Map<String, String> form_map;
  52. private boolean flag;//有没有验证码
  53. private String html;
  54. public Login() {
  55. super("人人登录");
  56. client = new DefaultHttpClient();
  57. responseHandler = new BasicResponseHandler();
  58. form_map = new HashMap<String, String>();
  59. Object obj;
  60. setLayout(null);
  61. setDefaultCloseOperation(EXIT_ON_CLOSE);
  62. setResizable(false);
  63. email = new JTextField("<email>");
  64. password = new JPasswordField("<password>");
  65. verifycode = new JTextField();
  66. login = new JButton("登录");
  67. login.addActionListener(this);
  68. html = view("http://3g.renren.com");
  69. init();
  70. try {
  71. imageBox = new ImageBoxPanel(createBufferedImage());
  72. } catch (Exception e) {
  73. e.printStackTrace();
  74. imageBox = new ImageBoxPanel();
  75. }
  76. //layout
  77. this.setBounds(500, 300, 280, 220);
  78. email.setBounds(10, 10, 250, 30);
  79. password.setBounds(10, 50, 250, 30);
  80. verifycode.setBounds(10, 90, 150, 30);
  81. imageBox.setBounds(205, 80, 54, 46);
  82. login.setBounds(10, 130, 250, 30);
  83. add(email);
  84. add(password);
  85. add(verifycode);
  86. add(imageBox);
  87. add(login);
  88. setVisible(true);
  89. }
  90. private BufferedImage createBufferedImage() {
  91. InputStream inputstream=null;
  92. try {
  93. String source = view("http://3g.renren.com");
  94. String url = getVerifycodeUrl(source);
  95. if("error".equals(url)) {
  96. return null;
  97. }
  98. ///rndimg?post=_REQUESTFRIEND_de6073b242a6fc34b67d228abf982916&rnd=1335096399071
  99. //分析登录表单可以发现如果某次登录需要验证码, 则表单中会有verifykey和verifycode
  100. //而verifykey 的值正好是验证码地址中的一部分(中间的32位字符), 所以把verifykey取出来
  101. String key = url;
  102. key = key.replaceAll("http[\\d\\D]*ND_", "");
  103. key = key.replaceAll("&[\\d\\D]*", "");
  104. form_map.put("verifykey", key);//更新下verifykey,和当前验证码对应
  105. System.out.println(key);
  106. get = new HttpGet(url);
  107. response = client.execute(get);
  108. if(HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {//以下两个if是网上摘来得
  109. HttpEntity entity = response.getEntity();
  110. if (entity != null) {
  111. inputstream = entity.getContent();
  112. //本来返回的是一个InputStream, 但是在finally中调用get.abort()后好像会变成null, 没办法, 所以直接构造出BufferedImage返回
  113. return ImageIO.read(inputstream);
  114. }
  115. }
  116. } catch (Exception e) {
  117. e.printStackTrace();
  118. } finally {
  119. get.abort();
  120. }
  121. return null;
  122. }
  123. /**
  124. * 获取某个url的html代码
  125. * @param url
  126. * @return
  127. */
  128. private String view(String url) {
  129. String html;
  130. try {
  131. get = new HttpGet("http://3g.renren.com/");
  132. html = client.execute(get, responseHandler);
  133. } catch (Exception e) {
  134. e.printStackTrace();
  135. html = "error";
  136. } finally {
  137. get.abort();
  138. }
  139. return html;
  140. }
  141. /**
  142. * 获取验证码图片的地址
  143. * @param source 某个页面的页面源代码
  144. * @return
  145. */
  146. private String getVerifycodeUrl(String source) {
  147. String url;
  148. flag = true;
  149. try {
  150. Document doc = Jsoup.parse(source);
  151. //分析表单可知此句可用, 不过用这种方法来做比较不好的一点就是一旦人人页面稍微改动下, 这个程序就可能用不了了
  152. Element e = doc.getElementsByAttributeValueContaining("alt", "此处为验证码").get(0);
  153. url = e.attr("src");
  154. url = "http://3g.renren.com" + url;
  155. } catch (Exception e) {
  156. //本来会打印异常信息, 不过看着不舒服, 就删了
  157. //大致就是有时没有验证码, 那么上面的get(0)肯定就行不通了
  158. System.out.println("没有验证码~");
  159. url = "error";
  160. flag = false;//标记有没有验证码, 可以让verifykey 和 verifycode 两个属性是否通过表单传过去
  161. }
  162. return url;
  163. }
  164. private void init() {
  165. String html = view("http://3g.renren.com");
  166. Document doc = Jsoup.parse(html);//取出3g.renren.com代码
  167. Element form = doc.getElementsByTag("form").get(0);
  168. String action = form.attr("action");
  169. form_map.put("action", action);
  170. Elements es = form.getElementsByTag("input");
  171. for(Element e: es) {
  172. form_map.put(e.attr("name"), e.attr("value"));
  173. }
  174. }
  175. @Override
  176. public void actionPerformed(ActionEvent e) {
  177. login();
  178. System.out.println(view("http://3g.renren.com"));
  179. //登录成功后显示发心情的界面, 主要实现了个功能, 没有考虑到其他的方面
  180. //包括是否登录成功啊, 是否发心情成功失败啊
  181. //不过这些还是挺简单的, 无非就是解析post后的html代码, 看会不会出现哪些错误信息
  182. box = new MsgBox();
  183. }
  184. private boolean login() {
  185. post = new HttpPost(form_map.get("action"));
  186. //据说有些网站如果不设置头会被过滤掉, 毕竟人人还是蛮大的一个网站, 就加上吧
  187. post.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3");
  188. List<NameValuePair> nvp = new ArrayList<NameValuePair>();
  189. nvp.add(new BasicNameValuePair("origURL", form_map.get("origURL")));
  190. nvp.add(new BasicNameValuePair("lbskey", form_map.get("lbskey")));
  191. nvp.add(new BasicNameValuePair("c", form_map.get("c")));
  192. nvp.add(new BasicNameValuePair("ref", form_map.get("ref")));
  193. nvp.add(new BasicNameValuePair("email", email.getText()));
  194. nvp.add(new BasicNameValuePair("password", new String(password.getPassword())));
  195. nvp.add(new BasicNameValuePair("pq", form_map.get("pq")));
  196. if(flag) {
  197. nvp.add(new BasicNameValuePair("verifycode", verifycode.getText()));
  198. nvp.add(new BasicNameValuePair("verifykey", form_map.get("verifykey")));
  199. }
  200. //  System.out.println(form_map.get("verifykey"));
  201. try {
  202. post.setEntity(new UrlEncodedFormEntity(nvp, HTTP.UTF_8));
  203. //response = client.execute(post);
  204. client.execute(post);
  205. } catch (Exception e) {
  206. e.printStackTrace();
  207. return false;
  208. } finally {
  209. post.abort();
  210. }
  211. return true;
  212. }
  213. public static void main(String[] args) {
  214. Login renren = new Login();
  215. //  System.out.println(renren.view("http://3g.renren.com"));
  216. }
  217. class MsgBox extends JFrame implements ActionListener {
  218. JTextArea msg;
  219. JButton submit;
  220. //某条心情发送次数, 本来想搞个刷屏的, 不过不太给力, 设置了休眠一段时间还是可以成功的
  221. JTextField time;
  222. public MsgBox() {
  223. setLayout(null);
  224. setResizable(false);
  225. setBounds(500, 500, 365, 125);
  226. msg = new JTextArea();
  227. submit = new JButton("发送~");
  228. time = new JTextField("1");
  229. msg.setBounds(10, 10, 250, 80);
  230. time.setBounds(270, 10, 81, 40);
  231. submit.setBounds(270, 50, 80, 40);
  232. submit.addActionListener(this);
  233. add(msg);
  234. add(submit);
  235. add(time);
  236. setVisible(true);
  237. }
  238. @Override
  239. public void actionPerformed(ActionEvent e) {
  240. for(int i = 0; i < Integer.parseInt(time.getText()); i++) {
  241. post = new HttpPost("http://3g.renren.com/status/wUpdateStatus.do");//反正都是从先认为的登录, 再把一些信息抓下来
  242. post.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3");
  243. List<NameValuePair> nvp = new ArrayList<NameValuePair>();
  244. nvp.add(new BasicNameValuePair("_rtk", "xxxxxxxx"));//这个不知道是怎么产生的, 可能每一个id都有对应一个把
  245. nvp.add(new BasicNameValuePair("sour", ""));
  246. nvp.add(new BasicNameValuePair("loginbybm", ""));
  247. nvp.add(new BasicNameValuePair("status", msg.getText() + i));//其他几个都无关紧要, 不过还是留着
  248. nvp.add(new BasicNameValuePair("pid", ""));
  249. nvp.add(new BasicNameValuePair("empty", "1"));
  250. try {
  251. post.setEntity(new UrlEncodedFormEntity(nvp, HTTP.UTF_8));
  252. response = client.execute(post);
  253. System.out.println(response);
  254. Thread.sleep(1000L);//没有设置休眠应该是被人人过滤掉了,具体多少时间间隔可以发一次没有测试过, 不过估计500毫秒应该是没有问题的吧
  255. } catch (Exception e1) {
  256. e1.printStackTrace();
  257. } finally {
  258. post.abort();
  259. }
  260. }
  261. }
  262. }
  263. }
  264. class ImageBoxPanel extends JPanel {
  265. private Image image;
  266. public ImageBoxPanel(Image image) {
  267. this.image = image;
  268. }
  269. public ImageBoxPanel() {
  270. }
  271. @Override
  272. protected void paintComponent(Graphics g) {
  273. g.drawImage(image, 0, 0, 54, 46, null);
  274. }
  275. }
  276. 转载出处:http://blog.csdn.net/ping_qc/article/details/7487352

httpclient 人人网的更多相关文章

  1. HTTPClient实现java自动登录人人网

    参考网址: https://passport.csdn.net/account/login  http://www.iteye.com/topic/638206 httpClient http://b ...

  2. 一步步教你为网站开发Android客户端---HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新ListView

    本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...

  3. Annotation 与 HttpClient(5)--Annotation HttpClient

    Annotation HttpClient 本内容不保证正确性,如有问题请及时提出 经过前面四篇博客的铺垫,现在给出带有标记的HttpClient的实现. 1.     带标记的HttpClient的 ...

  4. HttpClient的Post和Get訪问网页

    一.基础JAR包 Mavenproject下pom.xml需配置的jar包 <dependencies> <dependency> <groupId>junit&l ...

  5. 爬虫概念与编程学习之如何爬取视频网站页面(用HttpClient)(二)

    先看,前一期博客,理清好思路. 爬虫概念与编程学习之如何爬取网页源代码(一) 不多说,直接上代码. 编写代码 运行 <!DOCTYPE html><html><head& ...

  6. HttpClient的替代者 - RestTemplate

    需要的包 ,除了Spring的基础包外还用到json的包,这里的数据传输使用json格式 客户端和服务端都用到一下的包 <!-- Spring --> <dependency> ...

  7. 关于微软HttpClient使用,避免踩坑

    最近公司对于WebApi的场景使用也越来越加大了,随之而来就是Api的客户端工具我们使用哪个?我们最常用的估计就是HttpClient,在微软类库中命名空间地址:System.Net.Http,是一个 ...

  8. 使用HttpClient的优解

    新工作入职不满半周,目前仍然还在交接工作,适应环境当中,笔者不得不说看别人的源码实在是令人痛苦.所幸今天终于将大部分工作流畅地看了一遍,接下来就是熟悉框架技术的阶段了. 也正是在看源码的过程当中,有一 ...

  9. Java的异步HttpClient

    上篇提到了高性能处理的关键是异步,而我们当中许多人依旧在使用同步模式的HttpClient访问第三方Web资源,我认为原因之一是:异步的HttpClient诞生较晚,许多人不知道:另外也可能是大多数W ...

随机推荐

  1. php面向对象的基础:创建OOP的方法

    方法的创建 class Computer{ public function _run(){ return '我是类的一个公共方法'; } } $computer = new Computer(); / ...

  2. lua中pairs和ipairs的区别

    标准库提供了集中迭代器,包括迭代文件每行的(io.lines),迭代table元素的(pairs),迭代数组元素的(ipairs),迭代字符串中单词的 (string.gmatch)等等.LUA手册中 ...

  3. 使用单用户模式破解Linux密码

    使用单用户模式破解Linux密码 特别说明:在实际工作应用中,安装Linux操作系统必须设置装载口令,否则很容易被破解. 1.使用reboot指令重启Linux操作系统 2.在进入操作系统数秒时,单击 ...

  4. c++ string 拼接 int错误

    程序中用到字符串和int合成字符串,受java习惯的影响,直接进行了字符串与int的+操作,结果不正确.查了一下才明白问题所在,记录一下string str=”abc”+1;输出为:bc,因为”abc ...

  5. Linux美化——终端提示符

    1. PS1变量简介[1] PS1是Linux终端用户的一个环境变量,用来说明命令行提示符的设置. 可以使用 man bash命令查看bash手册,找到该变量支持的特殊字符,以及这些特殊字符的意义: ...

  6. 浅析 GRUB 如何加载 linux kernel

    前言 对于 GRUB 的加载流程,网上绝大部分都是写对 menu.lst, grub.cfg 这些 GRUB 配置文件的编写流程,就像是写脚本语言一样,用些关键字就能让 PC机能正确启动桌面 Linu ...

  7. silverlight 文本框只能输入汉字

    private void txtName_KeyDown(object sender, KeyEventArgs e) { Regex rg = new Regex("^[\u4e00-\u ...

  8. 高德amap 根据坐标获取的地址信息

    高德地理逆地理编码接口List<List<Address>> lists = coder.getFromLocation(33.00, 116.500, 3, 3, 3, 50 ...

  9. DML,DDL,DCL,DQL的区别

      DML 英文缩写 DML = Data Manipulation Language,数据操纵语言,命令使用户能够查询数据库以及操作已有数据库中的数据的计算机语言.具体是指是UPDATE更新.INS ...

  10. GGS: Sybase to Oracle

    Step 1: Start the GGSCI on Source and Target Source Target Oracle GoldenGate Command Interpreter for ...