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