爬虫记忆——【基础】简化httpclient的使用

        在上一篇文章中,简单介绍了httpclient的最基本的使用方式,并且通过httpclient获取里百度首页的页面信息,但是有没有发现一个问题,这么简单的一个操作,却写了不少的代码!程序员其实都挺懒的,这么不优雅的编程方式肯定受不了啊,那现在,我们再定一个小目标,我们将对httpclient进一步封装,封装完成之后,希望最好通过一行代码就能获取某个网页的信息!

        既然要封装,那首先需要建一个class,就取名叫MyHttpClient吧,这里面需要两个方法,分别是以get、post方式获取网页信息,信息以字符串的形式返回,我们先来搭好框架,代码如下所示:

public class MyHttpClient {
    public MyHttpClient() {
    }

    /**
     * 以get的方式请求网页
     *
     * @param url     网址
     * @param charset 编码
     * @param headers 请求头
     * @return 网页信息
     * @throws Exception
     */
    public synchronized static String get(String url, String charset, Map<String, String> headers) throws Exception {
        return "";
    }

    /**
     * 以post的方式请求网页
     *
     * @param url     网址
     * @param charset 编码
     * @param headers 请求头
     * @return 网页信息
     * @throws Exception
     */
    public synchronized static String post(String url, String charset, Map<String, String> headers) throws Exception {
        return "";
    }
}

        接下来,需要稍微讲解一下httpclient是如何管理连接的,通过阅读源代码,发现它在执行请求的时候,是委托给了ConnectionManager去创建连接的,ConnectionManager有多个子类,在这里,我们就使用MultiThreadedHttpConnectionManager去管理连接,MultiThreadedHttpConnectionManager使用了连接池的思想,在性能和资源消耗等方面都比较好。由于MultiThreadedHttpConnectionManager管理器一般只需设置一次即可,所以可以将其写成static的,代码如下:

private static MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

static {
    //超时
    Integer MAX_TIME_OUT = 5000;
    //最大连接数
    Integer MAX_CONN = 5000;
    connectionManager.closeIdleConnections(MAX_TIME_OUT);
    connectionManager.getParams().setParameter("http.connection-manager.max-total", MAX_CONN);
}

        最后,就可以将上一篇文章中的代码稍作修改,填入MyHttpClient中的get和post方法中了,完整代码如下所示:

public class MyHttpClient {
    public MyHttpClient() {
    }

    private static MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();

    static {
        //超时
        Integer MAX_TIME_OUT = 5000;
        //最大连接数
        Integer MAX_CONN = 5000;
        connectionManager.closeIdleConnections(MAX_TIME_OUT);
        connectionManager.getParams().setParameter("http.connection-manager.max-total", MAX_CONN);
    }

    /**
     * 以get的方式请求网页
     *
     * @param url     网址
     * @param charset 编码
     * @param headers 请求头
     * @return 网页信息
     * @throws Exception
     */
    public synchronized static String get(String url, String charset, Map<String, String> headers) throws Exception {
        //使用connectionManager实例化HttpClient
        HttpClient httpClient = new HttpClient(connectionManager);
        //按照指定编码去请求网页
        httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);
        //以GET的方式获取数据
        HttpMethod method = new GetMethod(url);
        //设置请求头
        if (headers != null) {
            Set<String> keys = headers.keySet();
            for (String k : keys) {
                method.setRequestHeader(k, headers.get(k));
            }
        }
        //执行,发送请求
        httpClient.executeMethod(method);
        //页面内容
        String result = method.getResponseBodyAsString();
        //释放连接
        method.releaseConnection();
        return result;
    }

    /**
     * 以post的方式请求网页
     *
     * @param url     网址
     * @param charset 编码
     * @param headers 请求头
     * @return 网页信息
     * @throws Exception
     */
    public synchronized static String post(String url, String charset, Map<String, String> headers) throws Exception {
        //使用connectionManager实例化HttpClient
        HttpClient httpClient = new HttpClient(connectionManager);
        //按照指定编码去请求网页
        httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);
        //以GET的方式获取数据
        HttpMethod method = new PostMethod(url);
        //设置请求头
        if (headers != null) {
            Set<String> keys = headers.keySet();
            for (String k : keys) {
                method.setRequestHeader(k, headers.get(k));
            }
        }
        //执行,发送请求
        httpClient.executeMethod(method);
        //页面内容
        String result = method.getResponseBodyAsString();
        //释放连接
        method.releaseConnection();
        return result;
    }
}

        最后,来使用一下,过程就相当简单了,还是以获取百度首页的信息为例,其核心的代码其实就只有一行而已,具体的代码如下所示:

public static void main(String[] args) throws Exception {
        //需要获取数据的url
        String url = "https://www.baidu.com";
        //指定编码
        String charset = "utf-8";
        //设置请求头
        Map<String, String> headers = new HashMap<>();
        headers.put("Host", "www.baidu.com");
        headers.put("User-Agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " +
                        "Chrome/66.0.3359.181 Safari/537.36");

        //调用封装好的方法,请求网页,仅仅这一行是核心代码
        String html = MyHttpClient.get(url, charset, headers);
        System.out.println(html);
    }

        至此,我们就将httpclient做了进一步的封装,之后获取某个网页信息都可以如此使用,在之后的文章中,也就默认使用这里面的方法了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值