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代码说不定就用不了了
- package com.renren.main;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.image.BufferedImage;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import javax.imageio.ImageIO;
- import javax.swing.JButton;
- import javax.swing.JFrame;
- import javax.swing.JPanel;
- import javax.swing.JPasswordField;
- import javax.swing.JTextArea;
- import javax.swing.JTextField;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.HttpStatus;
- import org.apache.http.NameValuePair;
- import org.apache.http.client.ClientProtocolException;
- import org.apache.http.client.HttpClient;
- 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;
- import org.apache.http.protocol.HTTP;
- import org.jsoup.Jsoup;
- import org.jsoup.nodes.Document;
- import org.jsoup.nodes.Element;
- import org.jsoup.select.Elements;
- public class Login extends JFrame implements ActionListener{
- private JTextField email;
- private JPasswordField password;
- private JTextField verifycode;
- private JButton login;
- private ImageBoxPanel imageBox;
- private Image image;
- private MsgBox box;
- private final HttpClient client;
- private HttpPost post;
- private HttpGet get;
- private HttpResponse response;
- private ResponseHandler<String> responseHandler;
- private Map<String, String> form_map;
- private boolean flag;//有没有验证码
- private String html;
- public Login() {
- super("人人登录");
- client = new DefaultHttpClient();
- responseHandler = new BasicResponseHandler();
- form_map = new HashMap<String, String>();
- Object obj;
- setLayout(null);
- setDefaultCloseOperation(EXIT_ON_CLOSE);
- setResizable(false);
- email = new JTextField("<email>");
- password = new JPasswordField("<password>");
- verifycode = new JTextField();
- login = new JButton("登录");
- login.addActionListener(this);
- html = view("http://3g.renren.com");
- init();
- try {
- imageBox = new ImageBoxPanel(createBufferedImage());
- } catch (Exception e) {
- e.printStackTrace();
- imageBox = new ImageBoxPanel();
- }
- //layout
- this.setBounds(500, 300, 280, 220);
- email.setBounds(10, 10, 250, 30);
- password.setBounds(10, 50, 250, 30);
- verifycode.setBounds(10, 90, 150, 30);
- imageBox.setBounds(205, 80, 54, 46);
- login.setBounds(10, 130, 250, 30);
- add(email);
- add(password);
- add(verifycode);
- add(imageBox);
- add(login);
- setVisible(true);
- }
- private BufferedImage createBufferedImage() {
- InputStream inputstream=null;
- try {
- String source = view("http://3g.renren.com");
- String url = getVerifycodeUrl(source);
- if("error".equals(url)) {
- return null;
- }
- ///rndimg?post=_REQUESTFRIEND_de6073b242a6fc34b67d228abf982916&rnd=1335096399071
- //分析登录表单可以发现如果某次登录需要验证码, 则表单中会有verifykey和verifycode
- //而verifykey 的值正好是验证码地址中的一部分(中间的32位字符), 所以把verifykey取出来
- String key = url;
- key = key.replaceAll("http[\\d\\D]*ND_", "");
- key = key.replaceAll("&[\\d\\D]*", "");
- form_map.put("verifykey", key);//更新下verifykey,和当前验证码对应
- System.out.println(key);
- get = new HttpGet(url);
- response = client.execute(get);
- if(HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {//以下两个if是网上摘来得
- HttpEntity entity = response.getEntity();
- if (entity != null) {
- inputstream = entity.getContent();
- //本来返回的是一个InputStream, 但是在finally中调用get.abort()后好像会变成null, 没办法, 所以直接构造出BufferedImage返回
- return ImageIO.read(inputstream);
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- get.abort();
- }
- return null;
- }
- /**
- * 获取某个url的html代码
- * @param url
- * @return
- */
- private String view(String url) {
- String html;
- try {
- get = new HttpGet("http://3g.renren.com/");
- html = client.execute(get, responseHandler);
- } catch (Exception e) {
- e.printStackTrace();
- html = "error";
- } finally {
- get.abort();
- }
- return html;
- }
- /**
- * 获取验证码图片的地址
- * @param source 某个页面的页面源代码
- * @return
- */
- private String getVerifycodeUrl(String source) {
- String url;
- flag = true;
- try {
- Document doc = Jsoup.parse(source);
- //分析表单可知此句可用, 不过用这种方法来做比较不好的一点就是一旦人人页面稍微改动下, 这个程序就可能用不了了
- Element e = doc.getElementsByAttributeValueContaining("alt", "此处为验证码").get(0);
- url = e.attr("src");
- url = "http://3g.renren.com" + url;
- } catch (Exception e) {
- //本来会打印异常信息, 不过看着不舒服, 就删了
- //大致就是有时没有验证码, 那么上面的get(0)肯定就行不通了
- System.out.println("没有验证码~");
- url = "error";
- flag = false;//标记有没有验证码, 可以让verifykey 和 verifycode 两个属性是否通过表单传过去
- }
- return url;
- }
- private void init() {
- String html = view("http://3g.renren.com");
- Document doc = Jsoup.parse(html);//取出3g.renren.com代码
- Element form = doc.getElementsByTag("form").get(0);
- String action = form.attr("action");
- form_map.put("action", action);
- Elements es = form.getElementsByTag("input");
- for(Element e: es) {
- form_map.put(e.attr("name"), e.attr("value"));
- }
- }
- @Override
- public void actionPerformed(ActionEvent e) {
- login();
- System.out.println(view("http://3g.renren.com"));
- //登录成功后显示发心情的界面, 主要实现了个功能, 没有考虑到其他的方面
- //包括是否登录成功啊, 是否发心情成功失败啊
- //不过这些还是挺简单的, 无非就是解析post后的html代码, 看会不会出现哪些错误信息
- box = new MsgBox();
- }
- private boolean login() {
- post = new HttpPost(form_map.get("action"));
- //据说有些网站如果不设置头会被过滤掉, 毕竟人人还是蛮大的一个网站, 就加上吧
- 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");
- List<NameValuePair> nvp = new ArrayList<NameValuePair>();
- nvp.add(new BasicNameValuePair("origURL", form_map.get("origURL")));
- nvp.add(new BasicNameValuePair("lbskey", form_map.get("lbskey")));
- nvp.add(new BasicNameValuePair("c", form_map.get("c")));
- nvp.add(new BasicNameValuePair("ref", form_map.get("ref")));
- nvp.add(new BasicNameValuePair("email", email.getText()));
- nvp.add(new BasicNameValuePair("password", new String(password.getPassword())));
- nvp.add(new BasicNameValuePair("pq", form_map.get("pq")));
- if(flag) {
- nvp.add(new BasicNameValuePair("verifycode", verifycode.getText()));
- nvp.add(new BasicNameValuePair("verifykey", form_map.get("verifykey")));
- }
- // System.out.println(form_map.get("verifykey"));
- try {
- post.setEntity(new UrlEncodedFormEntity(nvp, HTTP.UTF_8));
- //response = client.execute(post);
- client.execute(post);
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- } finally {
- post.abort();
- }
- return true;
- }
- public static void main(String[] args) {
- Login renren = new Login();
- // System.out.println(renren.view("http://3g.renren.com"));
- }
- class MsgBox extends JFrame implements ActionListener {
- JTextArea msg;
- JButton submit;
- //某条心情发送次数, 本来想搞个刷屏的, 不过不太给力, 设置了休眠一段时间还是可以成功的
- JTextField time;
- public MsgBox() {
- setLayout(null);
- setResizable(false);
- setBounds(500, 500, 365, 125);
- msg = new JTextArea();
- submit = new JButton("发送~");
- time = new JTextField("1");
- msg.setBounds(10, 10, 250, 80);
- time.setBounds(270, 10, 81, 40);
- submit.setBounds(270, 50, 80, 40);
- submit.addActionListener(this);
- add(msg);
- add(submit);
- add(time);
- setVisible(true);
- }
- @Override
- public void actionPerformed(ActionEvent e) {
- for(int i = 0; i < Integer.parseInt(time.getText()); i++) {
- post = new HttpPost("http://3g.renren.com/status/wUpdateStatus.do");//反正都是从先认为的登录, 再把一些信息抓下来
- 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");
- List<NameValuePair> nvp = new ArrayList<NameValuePair>();
- nvp.add(new BasicNameValuePair("_rtk", "xxxxxxxx"));//这个不知道是怎么产生的, 可能每一个id都有对应一个把
- nvp.add(new BasicNameValuePair("sour", ""));
- nvp.add(new BasicNameValuePair("loginbybm", ""));
- nvp.add(new BasicNameValuePair("status", msg.getText() + i));//其他几个都无关紧要, 不过还是留着
- nvp.add(new BasicNameValuePair("pid", ""));
- nvp.add(new BasicNameValuePair("empty", "1"));
- try {
- post.setEntity(new UrlEncodedFormEntity(nvp, HTTP.UTF_8));
- response = client.execute(post);
- System.out.println(response);
- Thread.sleep(1000L);//没有设置休眠应该是被人人过滤掉了,具体多少时间间隔可以发一次没有测试过, 不过估计500毫秒应该是没有问题的吧
- } catch (Exception e1) {
- e1.printStackTrace();
- } finally {
- post.abort();
- }
- }
- }
- }
- }
- class ImageBoxPanel extends JPanel {
- private Image image;
- public ImageBoxPanel(Image image) {
- this.image = image;
- }
- public ImageBoxPanel() {
- }
- @Override
- protected void paintComponent(Graphics g) {
- g.drawImage(image, 0, 0, 54, 46, null);
- }
- }
- 转载出处:http://blog.csdn.net/ping_qc/article/details/7487352
httpclient 人人网的更多相关文章
- HTTPClient实现java自动登录人人网
参考网址: https://passport.csdn.net/account/login http://www.iteye.com/topic/638206 httpClient http://b ...
- 一步步教你为网站开发Android客户端---HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新ListView
本文面向Android初级开发者,有一定的Java和Android知识即可. 文章覆盖知识点:HttpWatch抓包,HttpClient模拟POST请求,Jsoup解析HTML代码,动态更新List ...
- Annotation 与 HttpClient(5)--Annotation HttpClient
Annotation HttpClient 本内容不保证正确性,如有问题请及时提出 经过前面四篇博客的铺垫,现在给出带有标记的HttpClient的实现. 1. 带标记的HttpClient的 ...
- HttpClient的Post和Get訪问网页
一.基础JAR包 Mavenproject下pom.xml需配置的jar包 <dependencies> <dependency> <groupId>junit&l ...
- 爬虫概念与编程学习之如何爬取视频网站页面(用HttpClient)(二)
先看,前一期博客,理清好思路. 爬虫概念与编程学习之如何爬取网页源代码(一) 不多说,直接上代码. 编写代码 运行 <!DOCTYPE html><html><head& ...
- HttpClient的替代者 - RestTemplate
需要的包 ,除了Spring的基础包外还用到json的包,这里的数据传输使用json格式 客户端和服务端都用到一下的包 <!-- Spring --> <dependency> ...
- 关于微软HttpClient使用,避免踩坑
最近公司对于WebApi的场景使用也越来越加大了,随之而来就是Api的客户端工具我们使用哪个?我们最常用的估计就是HttpClient,在微软类库中命名空间地址:System.Net.Http,是一个 ...
- 使用HttpClient的优解
新工作入职不满半周,目前仍然还在交接工作,适应环境当中,笔者不得不说看别人的源码实在是令人痛苦.所幸今天终于将大部分工作流畅地看了一遍,接下来就是熟悉框架技术的阶段了. 也正是在看源码的过程当中,有一 ...
- Java的异步HttpClient
上篇提到了高性能处理的关键是异步,而我们当中许多人依旧在使用同步模式的HttpClient访问第三方Web资源,我认为原因之一是:异步的HttpClient诞生较晚,许多人不知道:另外也可能是大多数W ...
随机推荐
- GCD Block
GCD (Grand Central Dispatch) 是Apple公司开发的一种技术,它旨在优化多核环境中的并发操作并取代传统多线程的编程模式. 在Mac OS X 10.6和IOS 4.0之后开 ...
- Css调整字体间距
在span div 某些元素中有时候会用到调整字体的间距,设置方法: letter-spacing:15px;
- 配置普通用户可以运行saltstack的模块
client_acl 配置使用 1.概述:开启对系统上非root的系统用户在master上可以执行特殊的模块.这些模块名可以使用正则表达式来表示,不能指定对哪些minion执行命令.执行命令只需要切换 ...
- WCF 配置文件(三)
配置文件概述 WCF服务配置是WCF服务编程的主要部分.WCF作为分布式开发的基础框架,在定义服务以及定义消费服务的客户端时,都使用了配置文件的方法.虽然WCF也提供硬编程的方式,通过在代码中直接设置 ...
- 错误解决mysql - Event Scheduler: No data - zero rows fetched, selected, or processed
当遇到一个NOT FOUND(无数据)的警告时,使用一个包含清除警告语句的条件句柄处理,就可以继续处理程序并退出句柄. 这个问题在MySQL5.6.3之后的版本已经解决了,所以该解决方法不是必要的. ...
- Oracle中排序列中值相同引发的问题(译)
This queston came up on the Oracle newsgroup a few days ago: 这个问题在Oracle的新闻中心被提出了一段时间: I have a tabl ...
- 关于无限分类的树状输出(id,name,pid)类型的
首先创建无限分类的数据表,我这里采用的是id.name.pid这种类型(当然还有很多种无限分类的方式了,比如:id.name.pid.path.left.right左右节点的形式) CREATE TA ...
- Python中Cookie的处理(一)Cookie库
Cookie用于服务器实现会话,用户登录及相关功能时进行状态管理.要在用户浏览器上安装cookie,HTTP服务器向HTTP响应添加类似以下内容的HTTP报头: Set-Cookie:session= ...
- (一)使用log4net生成日志文件
1.引入log4net.dll 1.1 Nuget安装 或 http://logging.apache.org/log4net/下载log4net的源代码,编译后把log4net.dll引入项目. 2 ...
- SQLite清空表并将自增列归零[转]
SQL标准中有 WHERE name = 'TableName'; 也可以直接把该记录删掉: 1 DELETE FROM sqlite_sequence WHERE name = 'TableName ...