1. 程式人生 > >HttpClient模擬瀏覽器登入後發起請求(攜帶Cookie發請求)

HttpClient模擬瀏覽器登入後發起請求(攜帶Cookie發請求)

大家都知道 使用httpClient能模擬瀏覽器發起請求,得到想要的反回結果。
但在網際網路中存在這樣一種情況,某些資源只有登入後才可以檢視或下載
例如:百度文庫、部分論壇(只有登入後才可以看某些板塊)
瀏覽器實現這個效果需要如下幾個步驟:

Ø 1請求一個需要登入的頁面或資源
Ø 2伺服器判斷當前的會話是否包含已登入資訊。如果沒有登入重定向到登入頁面
Ø 3手工在登入頁面錄入正確的賬戶資訊並提交
Ø 4伺服器判斷登入資訊是否正確,如果正確則將登入成功資訊儲存到session中
Ø 5登入成功後伺服器端給瀏覽器返回會話的SessionID資訊儲存到客戶端的Cookie中
Ø 6瀏覽器自動跳轉到之前的請求地址並攜帶之前的Cookie(包含登入成功的SessionID)
Ø 7伺服器端判斷session中是否有成功登入資訊,如果有則將請求的資源反饋給瀏覽器



下面使用HttpClient模擬上述過程,這裡只實現手工發起登入,並攜帶Cookie發起第二次請求資源的過程。(網上實際有過好多這樣的例子,這裡只是自己寫出來備忘)

此處請求的是Iteye的部落格主頁,其他地址需要手動構建下URL。

 本文是一個的是 httpClient 4.2.5 httpCore 4.2.4  

有這兩個jar包

使用maven構建的,需要下載jar包的可以使用新增如下依賴
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.2.5</version>
</dependency>

沒有maven支援的也可以到apache的網站上去下載,方式有好多種或聯絡我

下面給出Java程式碼

package org.jshand.utils.http;

import java.io.FileOutputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.util.EntityUtils;

/**
 * TODO(用一句話描述該檔案的作用)
 *
 * @title: HttpClientDemo.java
 * @author zhangjinshan-ghq
 * @date 2014-6-11 14:59:04
 */

public class HttpClientDemo
{

    /**
     * The main method.
     *
     * @param args the arguments
     * @throws Exception the exception
     */
    public static void main(String[] args) throws Exception
    {
        getResoucesByLoginCookies();
    }

    /**
     * 根據登入Cookie獲取資源
     * 一切異常均未處理,需要酌情檢查異常
     *
     * @throws Exception
     */
    private static void getResoucesByLoginCookies() throws Exception
    {
        HttpClientDemo demo = new HttpClientDemo();
        String username = "XXXXXXXXX";// 登入使用者
        String password = "XXXXXXXX";// 登入密碼

        // 需要提交登入的資訊
        String urlLogin = "http://www.iteye.com/login?name=" + username + "&password=" + password;

        // 登入成功後想要訪問的頁面 可以是下載資源 需要替換成自己的iteye Blog地址
        String urlAfter = "http://314649444.iteye.com/";

        DefaultHttpClient client = new DefaultHttpClient(new PoolingClientConnectionManager());

        /**
         * 第一次請求登入頁面 獲得cookie
         * 相當於在登入頁面點選登入,此處在URL中 構造引數,
         * 如果引數列表相當多的話可以使用HttpClient的方式構造引數
         * 此處不贅述
         */
        HttpPost post = new HttpPost(urlLogin);
        HttpResponse response = client.execute(post);
        HttpEntity entity = response.getEntity();
        CookieStore cookieStore = client.getCookieStore();
        client.setCookieStore(cookieStore);

        /**
         * 帶著登入過的cookie請求下一個頁面,可以是需要登入才能下載的url
         * 此處使用的是iteye的部落格首頁,如果登入成功,那麼首頁會顯示【歡迎XXXX】
         *
         */
        HttpGet get = new HttpGet(urlAfter);
        response = client.execute(get);
        entity = response.getEntity();

        /**
         * 將請求結果放到檔案系統中儲存為 myindex.html,便於使用瀏覽器在本地開啟 檢視結果
         */

        String pathName = "d:\\myindex.html";
        writeHTMLtoFile(entity, pathName);
    }

    /**
     * Write htmL to file.
     * 將請求結果以二進位制形式放到檔案系統中儲存為.html檔案,便於使用瀏覽器在本地開啟 檢視結果
     *
     * @param entity the entity
     * @param pathName the path name
     * @throws Exception the exception
     */
    public static void writeHTMLtoFile(HttpEntity entity, String pathName) throws Exception
    {

        byte[] bytes = new byte[(int) entity.getContentLength()];

        FileOutputStream fos = new FileOutputStream(pathName);

        bytes = EntityUtils.toByteArray(entity);

        fos.write(bytes);

        fos.flush();

        fos.close();
    }

}