爬虫模拟登陆博客园,爬取信息,发送"闪存"消息等操作(微博、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。

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

 

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

 

posted @ 2014-08-20 19:53  白来了123  阅读(1820)  评论(2编辑  收藏  举报