牛骨文教育服务平台(让学习变的简单)
博文笔记

java爬虫

创建时间:2015-10-16 投稿人: 浏览次数:1100

java和python制作爬虫各有特点,但都需要用到已经封装好的类,下面开始一步一步的讲解,当作整理。


java爬虫

第一步:写出最核心的方法(执行GET请求,返回请求的HTML页面)

1.真对无需cookie的网站而言:

//url为请求页面地址,queryString为查询参数,可以为null,encode为编码字符集
public static String doGet(String url, String queryString, String encode) {
    String response = null;
    HttpClient client = new HttpClient();
    client.getParams().setConnectionManagerTimeout(3000);
    client.getParams().setSoTimeout(10000);
    HttpMethod method = new GetMethod(url);
    try {
        if (StringUtils.isNotBlank(queryString)) {
            method.setQueryString(URIUtil.encodeQuery(queryString));                
        }
        method.addRequestHeader("Content-Type" ,"application/x-www-form-urlencoded; charset="+encode);
        method.addRequestHeader("User-Agent",getUserAgent(random.nextInt(22)));
        client.executeMethod(method);

        if (method.getStatusCode() == HttpStatus.SC_OK) {
             InputStream in = method.getResponseBodyAsStream();  
                //这里的编码规则要与上面的相对应  
                BufferedReader br = new BufferedReader(new InputStreamReader(in,encode));  
                String tempbf;  
                StringBuffer html = new StringBuffer();  
                while ((tempbf = br.readLine()) != null) {  
                    html.append(tempbf +"
");  
                }  
                in.close();
                br.close();
               response=html.toString();
        }
    } catch (Exception e) {
        e.printStackTrace();
        log.error("doGet", e);

    } finally {
        method.releaseConnection();
        client.getHttpConnectionManager().closeIdleConnections(0);

    }
    return response;
}

2.针对需要cookie才能访问的网站而言:
需要在浏览器中查看访问该网站产生的cookie,并分析访问网址的时候服务器会检查哪些参数。从中寻找规律,并拼接成请求头信息,通过method.addRequestHeader;方法添加到请求头中。这样程序就会带参数访问网站。

    public static String doGet1(String url, String queryString, String encode) {
    String response = null;
    HttpClient client = new HttpClient();

    HttpMethod method = new GetMethod(url);
    try {
        if (StringUtils.isNotBlank(queryString)) {
            method.setQueryString(URIUtil.encodeQuery(queryString));    
        }
        method.addRequestHeader( "User-Agent","你的User-Agent");
        method.addRequestHeader( "User-Agent","你的。。。");
        method.addRequestHeader( "Referer","你的。。。");
        method.addRequestHeader( "Cookie","你的。。。");
        String cookieString = method.getResponseHeader("set-cookie").getValue();
        System.out.println(method.getRequestHeaders()[0].getValue());
        URL urlEX = new URL(url);
        URLConnection rulConnection = urlEX.openConnection(); 
        HttpURLConnection httpUrlConnection = (HttpURLConnection)rulConnection;
        List<String> cookieList = httpUrlConnection.getHeaderFields().get("Set-Cookie");
        for(int i=0;i<cookieList.size();i++) {
            System.out.println("cookie:"+cookieList.get(i));
        }
        //一下请求参数只供参考,网站不同需要的参数也不同
        //获取SUID
        String SUID = cookieList.get(1).substring(cookieList.get(1).indexOf("=")+1, cookieList.get(1).indexOf(";"));
        System.out.println("SUID:"+SUID);
        //获取SNUID
        String SNUID = cookieList.get(3).substring(cookieList.get(3).indexOf("=")+1, cookieList.get(3).indexOf(";"));
        //获取ABTEST
        String ABTEST = cookieList.get(4).substring(cookieList.get(4).indexOf("=")+1, cookieList.get(4).indexOf(";"));
        method.addRequestHeader("Cookie","ABTEST="+ABTEST+"; SNUID="+SNUID+";。。。等等");
        method.getParams().setContentCharset(encode);  
        //执行请求
        client.executeMethod(method);

        if (method.getStatusCode() == HttpStatus.SC_OK) {
            InputStream in = method.getResponseBodyAsStream();  
            //这里的编码规则要与上面的相对应  
            BufferedReader br = new BufferedReader(new InputStreamReader(in,encode));  
            String tempbf;  
            StringBuffer html = new StringBuffer();  
            while ((tempbf = br.readLine()) != null) {  
                html.append(tempbf +"
");  
            }  
           response=html.toString();
        }
    } catch (URIException e) {
        log.error("执行HTTP Get请求时,编码查询字符串错误" + queryString + "”发生异常!", e);
    } catch (IOException e) {
        log.error("执行HTTP Get请求" + url + "时,发生异常错误", e);
    } finally {
        method.releaseConnection();
        client.getHttpConnectionManager().closeIdleConnections(0);

    }
    return response;
}

第二步:业务逻辑的设计

获取到原始页面的html代码后,当然就是从中抓取自己需要的内容了。比较简单的方法就是用正则表达式来截取需要的内容。那么下面就讲解一下正则匹配的万能语法,非常简单:就是(.*?) 这个组合基本已经可以截取大多数的内容。
当然还是需要先封装好一个截取字符串的方法,如下:

   //pattern为正则表达式模式,str 原始字串,tagname基本无用,可指定为"a",返回的就是截取到的内容了
    public static final String fetchFirstStr( String str,String pattern,String tagname) {

if(str==null)
    return null;
    String list=null;
    try {
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(str);

        while (m.find()) {            
            list=m.group(1);
            break;
        }
        return list;
    } catch (PatternSyntaxException e) {
        e.printStackTrace();
        return list;
    }

在业务逻辑中调用上面的方法即可:

String str= fetchFirstStr(str, "截取内容前面的字符串(.*?)截取内容后面的字符串", "a");

好了现在str中便是你再该网页需要的内容了。

第三步:找到网页url变化的规律,循环爬取

对于一般网站而言,网页间的变化规律无非就是GET请求的page参数根据页数而变化,等等。这就需要根据业务的不同,因人而异了。

java爬虫总结:

1.需要的信息并不一定都在该html页面上,有些是以json返回的,有些需要再进入另一个页面中抓取,等等。所以遇到问题应该分析规律,思路要清晰。
2.上面的爬虫代码,只是针对非反爬虫的网站而言,对于专门反爬虫的网站而言,则需另寻它法。因为这类网站会不定时的更换cookie,又或者每次访问落地页,都需要上一级访问所产生的另一个参数,再或者过于频繁的访问就会触发禁止ip访问的功能。
针对反爬虫java可以使用HttpClient进行访问,然后记录每次访问后得到的cookie:

HttpClient client = new HttpClient();
client.getParams().setParameter(ClientPNames.COOKIE_POLICY,CookiePolicy.BROWSER_COMPATIBILITY);

这样需要先访问一次该网站不需cookie也能访问的页面,得到cookie后再进行目标落地页的爬取工作。但是所有访问都必须在这一个HttpClient对象中完成,只有当前这个HttpClient才保存有这次访问的cookie。

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。