其他爬蟲部落格:
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登入(本篇部落格)