httpclient 人人网

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

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

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

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

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

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

[java] view plaincopy

  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
时间: 2024-12-29 17:37:22

httpclient 人人网的相关文章

使用HttpClient模拟登录人人网+发状态+日志+分享+留言

事先使用HttpAnalyzer对人人网抓包观察,得到相关事件的数据.然后使用HttpClient模拟http请求相关操作.以下代码是今天刚测试过.欢迎新手拿去玩玩.注意:首先要在工程里导入httpclient的包,在apache官网上应该有的下载: http://hc.apache.org/downloads.cgi,目前是4.0+版本:其次记得将主函数里的账号和密码改为自己的,即可完成. import java.io.IOException; import java.io.Unsupport

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

先看,前一期博客,理清好思路. 爬虫概念与编程学习之如何爬取网页源代码(一) 不多说,直接上代码. 编写代码 运行 <!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=Edge" /><meta http-equiv="Content-Type" content="text/html; c

HttpClient的Post和Get访问网页

一.基础JAR包 Maven工程下pom.xml需配置的jar包 <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> <scope>test</scope> </dependency> <dependenc

用gson和httpclient调用微信公众平台API

吐槽:微信api很无语,部分用xml,部分用json. 最近在找如何调用微信公众平台关于json相关的api比较方便,最后发现httpcliect和gson不错.如果你有更好的方式,请告诉我. 以下代码先了解如何使用gson和httpclient,有功夫再整到我的sophia里 import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.

HttpClient使用详解 (一)

Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性.因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入. 一.简介 HttpClient是Apache Jakarta Common下的子项目,用

SpringMVC template和HttpClient post提交

服务器的接口如果是springmvc客户端除了用springmvc提供的RestTemplate请求如下 public class RestClient { private static Logger logger = Logger.getLogger(RestClient.class); @SuppressWarnings({ rawtypes, unchecked }) public static Object post(String url, Map<string, object="

Httpclient处理摘要认证

虽然摘要认证的安全性比BASIC认证提高了不少,但是从接口调用上来看,并不比BASIC认证复杂,而且Realm和Scheme参数都可以为空,这时候就和BASIC认证的调用方式一模一样了. import java.net.URI; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.Credentia

【黑马Android】(06)使用HttpClient方式请求网络/网易新闻案例

使用HttpClient方式请求网络 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"

使用Apache HttpClient访问网络(实现手机端注册,服务器返回信息)

这两天看了点网络编程,根据教程写了一个小的注册服务,贴出来. 本实例分别演示用GET方式和POST方式想服务器发送注册信息,分为客户端和服务器端两部分: 客户端注册用户信息,发送到服务器 服务器端接收信息并向客户端返回注册信息.(服务器端使用J2EE中的Servlet技术来实现,并发布到Tomcat服务器上) 代码运行效果如下: 客户端: 1.点击get注册按钮后: 客户端: 服务器端: 2.点击post注册按钮后: 客户端: 服务器端: 3.当服务器端关闭时: 客户端注册信息时会提示链接超时: