Java爬蟲入門簡介(三)——HttpClient保存、使用Cookie請求

其他爬蟲博客:

Java爬蟲入門簡介(一) —— HttpClient請求及其詳細使用 Java爬蟲入門簡介(二) —— Jsoup解析HTML頁面 Java爬蟲入門簡介(三) —— HttpClient保存和使用Cookie登錄(本篇博客)

Cookie是瀏覽器存儲存儲用户信息的一小段文本,它保存了用户的ID等信息,這些信息可以被服務器端識別,並作為標識用户的手段,以此來判定用户是不是第一次訪問。網絡上有這樣一段解釋,很清楚。

瀏覽器與WEB服務器之間是使用HTTP協議進行通信的;而HTTP協議是無狀態協議。也就是説,當某個用户發出頁面請求時,WEB服務器只是簡單的進行響應,然後就關閉與該用户的連接。因此當一個請求發送到WEB服務器時,無論其是否是第一次來訪,服務器都會把它當作第一次來對待,這樣的不好之處可想而知。為了彌補這個缺陷,Netscape開發出了cookie這個有效的工具來保存某個用户的識別信息, 它是一種WEB服務器通過瀏覽器在訪問者的硬盤上存儲信息的手段。 它是服務器發送給瀏覽器的體積很小的純文本信息。

定義:cookie是Web瀏覽器存儲的少量命名數據,它與某個特定的網頁和網站關聯在一起。cookie實際上和某一網站和網頁關聯的,保存用户一定信息的文本文檔。

Cookie是當你瀏覽某網站時,網站存儲在你機器上的一個小文本文檔,它記錄了你的用户ID,密碼、瀏覽過的網頁、停留的時間等信息,當你再次來到該網站時,網站通過讀取Cookie,得知你的相關信息,就可以做出相應的動作,如在頁面顯示歡迎你的標語,或者讓你不用輸入ID、密碼就直接登錄等等。

在這篇博客中,我們將描述在HttpClient 4.X中,如何使用Cookie,保存Cookie,並利用已登錄的Cookie訪問頁面。

首先,在HttpClient 4.X中,使用HttpContext來保存請求的上下文信息。説白了,就是用一個類來保存請求的信息。比如,如果使用HttpClient請求利用了HttpContext,那幺在請求的時候會帶有HttpContext裏面保存的一些信息,如sessionId等。同時,HttpClient請求完了之後也會把從服務器得到的一些信息保存下來,下次請求的時候,使用這個HttpContext就會帶上這次請求所保存的信息了。BasicHttpContext裏有個Map對象用來記錄一次請求響應的信息,當響應信息返回時,就會被set到context裏,當然響應的cookie信息也就被存儲在context裏,包括傳回的sessionId。當第二次請求的時候傳入相同的context,那幺請求的過程中會將context裏的sessionId提取出來傳給服務器,sessionId一樣,自然而然的就是同一個session對象。

下面我們看一個使用HttpContext帶Cookie請求的案例。

package org.hfutec.crawler.main;

import com.google.common.collect.Lists;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

public class RequestWithCookie {

  public static void main(String[] args) throws URISyntaxException, IOException, ClassNotFoundException {

    //待請求的地址
    String url = "http://www.datalearner.com";

    //請求參數
    List<NameValuePair> loginNV = new ArrayList<>();
    loginNV.add(new BasicNameValuePair("userName", "test"));
    loginNV.add(new BasicNameValuePair("passWord", "test"));

    //構造請求資源地址
    URI uri = new URIBuilder(url).addParameters(loginNV).build();

    //創建一個HttpContext對象,用來保存Cookie
    HttpClientContext httpClientContext = HttpClientContext.create();

    //構造自定義Header信息
    List<Header> headerList = Lists.newArrayList();
    headerList.add(new BasicHeader(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9," +
            "image/webp,image/apng,*/*;q=0.8"));
    headerList.add(new BasicHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
            "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"));
    headerList.add(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate"));
    headerList.add(new BasicHeader(HttpHeaders.CACHE_CONTROL, "max-age=0"));
    headerList.add(new BasicHeader(HttpHeaders.CONNECTION, "keep-alive"));
    headerList.add(new BasicHeader(HttpHeaders.ACCEPT_LANGUAGE, "zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,ja;q=0.2," +
            "de;q=0.2"));

    //構造自定義的HttpClient對象
    HttpClient httpClient = HttpClients.custom().setDefaultHeaders(headerList).build();

    //構造請求對象
    HttpUriRequest httpUriRequest = RequestBuilder.get().setUri(uri).build();

    //執行請求,傳入HttpContext,將會得到請求結果的信息
    httpClient.execute(httpUriRequest, httpClientContext);

    //從請求結果中獲取Cookie,此時的Cookie已經帶有登錄信息了
    CookieStore cookieStore = httpClientContext.getCookieStore();

    //這個CookieStore保存了我們的登錄信息,我們可以先將它保存到某個本地文檔,後面直接讀取使用
    saveCookieStore(cookieStore,"cookie");

    //下面我們將演示如何使用Cookie來請求,首先我們將之前的Cookie讀出來
    CookieStore cookieStore1 = readCookieStore("cookie");

    //構造一個帶這個Cookie的HttpClient
    HttpClient newHttpClient = HttpClientBuilder.create().setDefaultCookieStore(cookieStore1).build();

    //使用這個新的HttpClient請求就可以了。這時候我們的HttpClient已經帶有了之前的登錄信息,再爬取就不用登錄了
    newHttpClient.execute(httpUriRequest, httpClientContext);


  }

  //使用串行化的方式保存CookieStore到本地文檔,方便後續的讀取使用
  private static void saveCookieStore( CookieStore cookieStore, String savePath ) throws IOException {

    FileOutputStream fs = new FileOutputStream(savePath);
    ObjectOutputStream os =  new ObjectOutputStream(fs);
    os.writeObject(cookieStore);
    os.close();

  }

  //讀取Cookie的串行化文檔,讀取後可以直接使用
  private static CookieStore readCookieStore( String savePath ) throws IOException, ClassNotFoundException {

    FileInputStream fs = new FileInputStream("cookie");//("foo.ser");
    ObjectInputStream ois = new ObjectInputStream(fs);
    CookieStore cookieStore = (CookieStore) ois.readObject();
    ois.close();
    return cookieStore;


  }

}

這就是HttpClient 4.X如何使用Cookie的方式。使用現有的Cookie,其實只要把這個Cookie放到自定義的HttpClient中就行了,很簡單。

其他爬蟲博客:

Java爬蟲入門簡介(一) —— HttpClient請求及其詳細使用 Java爬蟲入門簡介(二) —— Jsoup解析HTML頁面 Java爬蟲入門簡介(三) —— HttpClient保存和使用Cookie登錄(本篇博客)

關鍵詞:HttpComponents

相關推薦:

使用httpClient獲取請求cookie

httpClient 連接池問題出現403.9

HttpClient實戰二:單線程和多線程連接池實例

一個c#的與web服務器交互的HttpClient類

Try the configuration session cookie by using HttpClient

Java HttpClient偽造請求之簡易封裝滿足HTTP以及HTTPS請求

廣州圖書館借閲抓取——httpClient的使用

HttpClient 連接池管理

httpclient開啟代理,獲取java中請求的url

httpclient pool幫助類