Fork me on GitHub
HttpClient的使用-爬虫学习1

HttpClient的使用-爬虫学习(一)

  Apache真是伟大,为我们提供了HttpClient.jar,这个HttpClient是客户端的http通信实现库,这个类库的作用是接受和发送http报文,引进这个类库,我们对于http的操作会变得简单一些,事不宜迟,赶快介绍。

  在将这个HttpClient之前,我们必须弄清两个概念:URL和URI

  URI(Universal Resource Identify),通用资源标识符,而URL(Uniform Resource Locator),统一资源定位符,两个有什么区别,其实就是范围大小的问题,URI是包含URL的,URI由访问资源的命名机制、存放资源的主机名、资源自身的路径组成,而URL由协议、资源的主机IP地址、主机资源的具体地址组成,有他们两个的组成我们可以清楚的看出,其实URL就是我们平时输入浏览器的地址,如“http://www.hao123.com”,URL是URI的具体表现形式而已,URI是包含URL的。

  下面正式学习HttpClient:

  我讲解的这个HttpClient版本是4.0以上的,如果要运行我的代码的话就要引用4.0以上的jar包。

  1.创建一个客户端,使用HttpClient,用它来处理与http相关的操作,我们可以理解为创建一个浏览器那样:

HttpClient httpClient = new DefaultHttpClient();

   2.创建一个HttpGet类,相当于与在浏览器中打开一个URL,该类的构造接受一个String类型的参数,就是我们要输入的URL了: 

HttpGet httpGet = new HttpGet("http://www.hao123.com");

   3.通过HttpClient的execute方法,参数为HttpGet类型的参数,相当于打进网址后回车,这个我们可以得到HttpResponse,这个是代表请求后对应的响应: 

HttpResponse response = httpClient.execute(httpGet);

   4.通过这个response我们可以拿到一个HttpEntity类的实体,这个实体里面有着Http报文的许多信息,当然包括我们想要的内容: 

HttpEntity entity = response.getEntity();

   5.通过entity这个实体,我们可以调用它的getContent方法,拿到的就是网页的内容,但这个内容是InputStream,不过有了InputStearm,什么都好办了: 

InputStream instream = entity.getContent();

 下面我们来看看一个完整的抓取www.hao123.com内容的实例:

复制代码
    @Test
    public void testGet() throws Exception {
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet("http://www.hao123.com");
        HttpResponse response = httpClient.execute(httpGet);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream instream = entity.getContent();
            int l;
            byte[] tmp = new byte[2048];
            while ((l = instream.read(tmp)) != -1) {
                System.out.println(new String(tmp, 0, l, "utf-8"));
            }
        }
    }
复制代码

 

下面具体一点来介绍:

  1.Http请求

  HttpClient支持所有定义在Http/1.1版本中的的方法:get、post、head、put、delete、trace和options,对应每个方法都有一个类:HttpGet、HttpPost、HttpHead、HttpPut、HttpDelete、HttpTrace和HttpOptions

  上面这些方法类中,除了可以有String参数的构造方法外,还有一个URI参数的构造方法,通过这个uri就发出请求,这个URI类其实我们jdk自带的,但是Apache真是为我们着想,提供了URIUtils类帮助我们,有兴趣可以去了解一下。

 

  2.Http响应

  HttpResponse是HttpClient提供给我们的响应类,响应是服务器发给客户端的报文,报文中包含了各种信息,通过下列方法我们可以拿到这些信息:

    getProtocolVersion():返回报文的协议版本

    getStatusLine():返回响应报文的第一行内容

    getStatusLine().getStatusCode():返回报文的状态码

示例:

复制代码
    @Test
    public void testResponseMethod() {
        //模拟一个响应
        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
        System.out.println("协议版本:" + response.getProtocolVersion());
        System.out.println("协议信息:" + response.getStatusLine());
        System.out.println("协议状态码:" + response.getStatusLine().getStatusCode());
    }
复制代码

 

  3.Http报文头部:

  一个http报文头部可以包含很多信息,如内容的长度、内容的类型等等各种各样的信息。HttpResponse有着很多方法处理头部的信息:

  addHeader(String name, String value):增加一个头部信息,一个key,一个value

  getFirstHeader(String name):拿到第一个header

  getLastHeader(String name):拿到最后一个header

  getHeads(String name):拿到一个head数组

  headerIterator(String name):拿到一个数组的迭代器

  不仅如此,通过HeaderElementIterator我们还可以迭代出里面value的信息,看示例:

 

复制代码
    @Test
    public void testHeadMethod() {
        HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
        response.addHeader("cookie", "c1=a;path=/;domain=localhost");
        response.addHeader("cookie", "c2=b;path=/guo;domain=localhost:8080");
        response.addHeader("cookie", "path=/ray;domain=localhost:3306");
        System.out.println(response.getFirstHeader("cookie"));
        System.out.println(response.getLastHeader("cookie"));
        System.out.println("---------------------------------------------");
        
        Header[] heads = response.getHeaders("cookie");
        for(Header head : heads)
            System.out.println(head);
        System.out.println("---------------------------------------------");
        
        HeaderIterator it = response.headerIterator();
        while(it.hasNext())
            System.out.println(it.next());
        System.out.println("---------------------------------------------");
        
        HeaderElementIterator hei = new BasicHeaderElementIterator(response.headerIterator());
        while(hei.hasNext()) {
            HeaderElement element = hei.nextElement();
            System.out.println(element.getName() + "=" + element.getValue());
            NameValuePair[] params = element.getParameters();
            for(NameValuePair name : params)
                System.out.println(name);
        }
    }
复制代码

 

   4.Http实体

  实体是响应请求成功发送到客户端时创建的,通过Entity我们可以拿到很多信息,看看下面的方法:

    getContent():这个拿到响应的内容,前面我们就用过了

    getContentType():拿到content的类型信息

    getContentLength():拿到content的长度

    通过EntityUtils类我们可以更加方法的拿到一些信息,看下面:

复制代码
    @Test
    public void testEntityMethod() throws Exception {
        StringEntity entity =  new StringEntity("username=xujianguo", "utf-8");
        System.out.println(entity.getContentType());
        System.out.println(entity.getContentLength());
        System.out.println(EntityUtils.toString(entity));
    }
复制代码

 

  5.Http状态码

状态码 描述
200     请求成功
201 请求完成,结果是创建了新资源
202   请求被接受,但处理还没完成
204 服务器已经完成了请求,但是没有返回新的信息
300 存在多个可用的被请求资源
301 请求道的资源都会分配一个永久的url
302 请求道的资源放在一个不同的url中临时保存
304 请求的资源未更新
400   非法请求
401 未授权
403   禁止
404     找不到页面

 

 
 
posted on 2013-12-16 23:53  HackerVirus  阅读(205)  评论(0编辑  收藏  举报