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));
}
效果如下:這就是某瓣的登入後的主頁