1. 程式人生 > >java爬蟲-0022,模擬登入

java爬蟲-0022,模擬登入

基本原理:使用者輸入登入資訊=>登入成功,伺服器將登入成功的資訊傳送的前臺,通常存在cookie中=>後續請求帶上登入成功的cookie資訊,在伺服器即視為登入成功

基本步驟:通過谷歌的開發者工具,抓取登入包=>分析出登入需要傳遞的資料(sublime全域性搜尋的妙用)=>請求伺服器=>獲取返回報文的cookie欄位(比較登入前後的cookie可以知道需要帶上什麼cookie)=>帶上cookie做後續請求。

1、通過谷歌開發者工具獲取登入資訊

    1.1 勾選preserve log,可以保證登入請求不會被登入成功請求刷掉。

    1.2 獲取登入登資訊

通過上面的分析,我們可以得知請求的地址和型別,還有請求引數,我們只需要拼湊出我們請求資料即可。其中引數的具體含義(猜想)

souce:不知道具體含義,不過似乎不會改變,

form_email :郵箱地址

form_password:密碼

captcha-solution: 驗證碼

captcha-id:看不出來

2、分析請求資料

分析請求資料是模擬登入中最難的一部分,這邊有一個小技巧:先儲存登入頁面的網頁資訊,利用sublime全域性搜尋關鍵字,具體如下:

    2.1 在登入介面右鍵->下載(網頁全部)

    2.2 檢視剛剛下載的html檔案,找到登入表單部分。(推薦使用sublime,一來可以美化,二來可以全域性搜尋)

由此可以知道每個欄位的具體含義

source :index_nav 多次實驗,該引數不會變

form_email :郵箱地址

form_password:密碼

captcha-solution: 驗證碼(可以呼叫百度ocr介面識別,不過識別率好像有點低)

上述四個欄位都容易解決,關鍵是最後一個引數,每次都會改變,應該是一個token,token的長生一般有兩種方式:1)伺服器產生,前臺獲取;2)前端通過js生成 

正確的處理思路:破解別人的token生成演算法(大神除外),而是找到人家加密的程式碼直接使用,方便快捷。

    2.3 sublime全域性搜尋

訪問報文如下

{"url":"\/\/www.douban.com\/misc\/captcha?id=WfQ1k5feHvtxDfVjz1Ztyg7m:en&size=s","token":"WfQ1k5feHvtxDfVjz1Ztyg7m:en","r":false}

看到這個應該就清楚了,其中url是驗證碼圖片的地址,token 就是令牌

到此為止就分析完了請求的引數,這邊算是比較簡單,只要一個令牌,通常名稱和密碼都會通過演算法加密,一般是js,但是js會被載入到前臺,所以只要通過sublime全域性搜尋一般就能定位到加密部分。通過node.js本地執行js程式碼可以驗證。

注:上述是在重複登入多次之後才會要求輸驗證碼和token,如果第一次登入是不需要的。那樣就更簡單了

3、登入獲取響應頭資料

/**
     * 第二個爬蟲程式,模擬登入
     */
    @Test
    public void crawlerClient_02() {
        String url = "https://www.douban.com/accounts/login";
        Map<String, Object> headerParams = new HashMap<>();
        headerParams.put(P.REQUEST.USER_AGENT, P.USER_AGENT);
        String requestParamsStr = "請求資料";
        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put(P.REQUEST.REQUEST_PARAMS, requestParamsStr);
        requestParams.put(P.REQUEST.CONTENT_TYPE, P.REQUEST.CONTENT_TYPE_FROM_URLENCODEED);
        Map<String, Object> resMap = Request.post(url, headerParams, requestParams);
        // 獲取請求頭
        Header[] headers = (Header[]) resMap.get(P.REQUEST.HEADERS);
        for(Header header : headers){
            System.out.println(header.getName() + ":" + header.getValue());
        }
    }

響應的報文頭,其中set-cookie包含了登入資訊,其實這就已經登入成功了

4、比較未登入頁面和登入頁面的cookie資訊,

登入後cookie比未登入cookie多一個dbc12,而這個dbc12會在登入的請求返回,所以我們在未登入cookie的基礎上帶上這個欄位

5、獲取需要登入的頁面資訊

  /**
     * 第三個爬蟲程式,模擬登入後獲取需要登入的資料
     */
    @Test
    public void crawlerClient_03() {
        String url = "https://www.douban.com";
        Map<String, Object> headerParams = new HashMap<>();
        headerParams.put(P.REQUEST.USER_AGENT, P.USER_AGENT);
        headerParams.put(P.REQUEST.COOKIE, P.COOKIE + "dbcl2=\"185440808:yJ+PWhiBL6w\"");
        Map<String, Object> resMap = Request.get(url, headerParams);
        System.out.println(resMap.get(P.REQUEST.RES_BODY));
    }

效果如下:這就是某瓣的登入後的主頁