zoukankan      html  css  js  c++  java
  • 爬虫模拟登陆博客园,爬取信息,发送"闪存"消息等操作(微博、BBS同理)

        

             朋友们,好久不见了。最近忙着其他事情,一直没有到博客园转转。你们还好吗?

            分享最近项目里面的一小段代码吧。

            描述:由于某种需要,需要抓取某些特定网站上的信息,其中有一些网站是需要登录后才能抓取信息的。这就牵扯到如何模拟登陆,登陆后又应该进行哪些处理可以爬取其他页面的信息。

            一般来说,需要登录的网站都没有禁用cookie,(如果对cookie和http协议不了解,请自行百度),一般模拟登陆都是利用这一特性进行的。

           主要过程如图所示:

     

            本人项目中代码也是大概这么一个过程,我利用了开源工具httpClient 。因为该工具对HTTP协议进行了很好的封装和管理,当然也实现了http中所有的协议,比如get,post等等。

    /*
         * 测试代码
        */
        public static void main(String[] args) throws ClientProtocolException, IOException {
            // TODO Auto-generated method stub
            
            String message="Hello,World!";
            DefaultHttpClient client=getHttpClient();
            if(sendMessage(client, message))
                System.out.println("发送成功");
            else 
                System.out.println("发送失败");
        }
        /***
         * 得到一个登陆后添加了cookie的连接。
         * 
         * @author http://www.cnblogs.com/xiaoyi115/
         * */
        public static DefaultHttpClient getHttpClient() throws ClientProtocolException, IOException{
            DefaultHttpClient client=new DefaultHttpClient();
            List<NameValuePair> nvps=getNameValuePairs();
            String uri="http://passport.cnblogs.com/login.aspx";
            List<Cookie> cookies=getCookies( nvps, uri);
            for (Cookie cookie : cookies) {
                client.getCookieStore().addCookie(cookie);
            }
            return client;
        }
        /***
         * 显示发送的消息是否成功
         * @param client 一个连接
         * @param message 需要发送的消息
         * @return 返回发送是否成功
         * @author http://www.cnblogs.com/xiaoyi115/
         * */
        public static boolean sendMessage(DefaultHttpClient client,String message) throws ParseException, IOException{
            HttpPost post=new HttpPost("http://home.cnblogs.com/ajax/ing/Publish");
            post.addHeader("Accept", "application/json, text/javascript, */*; q=0.01");
            post.addHeader("Accept-Encoding", "gzip,deflate,sdch");
            post.addHeader("Accept-Language", "zh-CN,zh;q=0.8,en;q=0.6");
            post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36");
            post.addHeader("Content-Type", "application/json; charset=UTF-8");
            post.addHeader("Origin", "http://passport.cnblogs.com");
            post.addHeader("Referer", "http://passport.cnblogs.com/login.aspx?ReturnUrl=http%3A%2F%2Fwww.cnblogs.com%2F");
            
            String xjson="{'content':'"+message+"','publicFlag':1}";
            StringEntity entity=new StringEntity(xjson,"utf-8");
            post.setEntity(entity);
            HttpResponse respons=client.execute(post);
            
            if(respons.getStatusLine().getStatusCode()==200&(EntityUtils.toString(respons.getEntity()).contains(message)))
                return true;
            else 
                return false;
            //System.out.println(respons.getStatusLine().getStatusCode());
            //System.out.println(EntityUtils.toString(respons.getEntity()));
        }
        /***
         * 登陆时需要post的对象
         * 
         * @return 返回对象集合
         * 
         * @author http://www.cnblogs.com/xiaoyi115/
         * */
        public static List<NameValuePair> getNameValuePairs(){
            ArrayList<NameValuePair> nvps=new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair("__VIEWSTATE", "/wEPDwUKMTk0MDM4Nzg5MGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFC2Noa1JlbWVtYmVy36jcXkF+JKEwq4mk1eC4ETqcaTA="));
            nvps.add(new BasicNameValuePair("__EVENTVALIDATION", "/wEdAAW9J9gK2KAJMjMp9r0ov6f2hI6Xi65hwcQ8/QoQCF8JIahXufbhIqPmwKf992GTkd0wq1PKp6+/1yNGng6H71Uxop4oRunf14dz2Zt2+QKDEEdfo2FEmOcxajQv/HKJB0yp2y8y"));
            nvps.add(new BasicNameValuePair("tbUserName", "潇一115"));
            nvps.add(new BasicNameValuePair("tbPassword", "*******"));
            nvps.add(new BasicNameValuePair("btnLogin", "登  录"));
            nvps.add(new BasicNameValuePair("txtReturnUrl", "http://www.cnblogs.com/"));
            return nvps;
        }
        /***
         * 得到登陆后的cookie
         * @return 返回cookies
         * 
         * @author http://www.cnblogs.com/xiaoyi115/
         * */
        public static List<Cookie> getCookies( List<NameValuePair> nvp,String uri) throws ClientProtocolException, IOException{
    
            DefaultHttpClient client=new DefaultHttpClient();
            HttpPost post=new HttpPost(uri);
            post.addHeader("Accept-Encoding", "gzip,deflate,sdch");
            post.addHeader("Accept-Language", "zh-CN,zh;q=0.8,en;q=0.6");
            post.addHeader("Content-Type", "application/x-www-form-urlencoded");
            post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36");
            post.addHeader("Origin", "http://passport.cnblogs.com");
            post.addHeader("Referer", "http://passport.cnblogs.com/login.aspx?ReturnUrl=http%3A%2F%2Fwww.cnblogs.com%2F");
            
            post.setEntity(new UrlEncodedFormEntity(nvp,HTTP.UTF_8));
            client.execute(post);
            List<Cookie> cookies=client.getCookieStore().getCookies();
            return cookies;
        }

             

              另外,对于爬虫来说,对网页的分析也是一件非常重要的事情。推荐开源工具htmlparser.

              新浪微博的登陆会比博客园的登陆稍微难一些。新浪微博会有一步预登陆,获取到一些信息,利用这些信息再进行登陆。

              当然,项目中的爬虫远比这个要复杂。需要多线程,既然用到了多线程,就要对线程进行管理、通信,牵扯多个线程如何配合的问题。另外爬取策略也需要考虑,一般爬取在大的方面会有深度优先和广度优先。当然,不是简单的深度或广度,一般需要进行优化,和停止策略。对于同一个站点,不能过于频繁的爬取,这样很容易被禁IP。

             爬虫需要了解的东西还很多。就扯这么多吧。

     

        版权所有,欢迎转载,但是转载请注明出处:潇一

     

  • 相关阅读:
    Redis常用数据类型及应用场景之Set
    Redis常用数据类型及应用场景之List
    Redis常用数据类型及应用场景之Hash
    exists & not exists
    oracle 中 dblink 的简单使用
    DockerCompose之数据卷Volume
    DockerCompose之常见编排脚本
    160308-学习State Pattern Actor
    12.3-框架维护
    12.2-机器人协作系统
  • 原文地址:https://www.cnblogs.com/xiaoyi115/p/3925404.html
Copyright © 2011-2022 走看看