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     找不到頁面

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM