爬蟲實戰篇(模擬登陸)---咱們以模擬去哪兒網爲例

(1)、登陸實質

互聯網上的部分網站須要登陸後方能訪問,當咱們打開網頁並登陸,就會在客戶端生成Cookies(至關於我的身份證)信息,Cookies中包含了SessionId信息,登陸後的請求都會帶上Cookies發送給服務器,服務器會根據Cookies判斷出對應的SessionID,進而找到會話,從而判斷用戶是否師登陸狀態,從而是否給用戶響應。html

(2)、什麼是模擬登錄

答:讓機器模擬人在瀏覽器上的行爲登陸網站chrome

(3)、實現方式

一、使用虛擬的瀏覽器json

步驟:請求登陸頁面的url----分析html中的表單數據----找到用戶名和密碼的輸入框----輸入本身的用戶名和密碼---模擬點擊登陸按鈕便可api

二、分析登陸信息提交方式,利用瀏覽器cookie模擬登陸瀏覽器

步驟:分析網頁結構,確認登陸方式,如帳號密碼登陸或掃碼登陸----如是帳號密碼登陸,確認有無驗證碼及驗證碼接口----進行錯誤登陸嘗試,觀察登陸系統的傳碼方案,如帳號密碼是否加密,是否有加密,是否有額外參數須要尋找,登陸須要傳入的cookie---根據錯誤登陸的分析結果,尋找額外的參數和須要傳入的cookie來源和密碼加密函數---反覆測試並編寫代碼服務器

(4)、實例講解(模擬登陸去哪兒網)--這裏咱們用第二種實現方式

一、本節目標:模擬去哪兒網的登陸過程並抓取信息

二、環境準備:

requests + re 庫cookie

三、知識儲備

cookie:用戶首次訪問一個域名時,服務器給用戶發送的數據,用來保持服務器與客戶端之間的狀態,這些數據即爲cookiesession

session:另外一種記錄客戶狀態的機制,不一樣於cookie保存於客戶機,它保存在服務器上,當客戶端瀏覽器訪問服務器時,服務器將客戶端的信息以某種形式記錄在服務器上,這就是session,而當客戶端再次發起請求,就會從該session中查找用戶的狀態dom

這裏作個類比:咱們將銀行比做服務器,而客戶端就是去銀行辦事的人員,cookie至關於咱們去銀行辦事時攜帶的身份證,被用來肯定用戶的身份,而session至關於銀行保存的客戶檔案用來覈實客戶身份。jsp

四、思路分析

(1)分析網頁登陸方式(這裏咱們使用chrome的無痕模式窗口   ctrl+shift+n),咱們發現有三種方式:帳號密碼登陸、短信驗證碼登陸、掃碼登陸,這裏咱們採起帳號密碼登陸方式

(2)分析驗證碼接口

(3)嘗試錯誤登陸,查看請求頁面的form data ,構造請求函數,嘗試使用爬蟲進行登陸,發現報錯,經過分析咱們發現須要傳入cookie的參數爲QN一、QN2五、QN27一、_i、_vi、fid

(4)尋找cookie來源,藉助chrome的開發者工具

(5)在session經過get請求添加須要的cookie,再次嘗試便可

五、代碼詳解:

首先獲取session--獲取cookies

 1 #author: "xian"
 2 #date: 2018/5/31
 3 
 4 import requests
 5 
 6 def get_start_session(): #獲取session
 7     s = requests.session()
 8     return s
 9 
10 def get_base_cookies(s): #獲得基礎的cookies,這裏使用session。get()發送請求,requests。get發送的請求互補干擾,相互獨立,而session.get發送的請求的cookie會自動合併
11     response = s.get('https://user.qunar.com/passport/login.jsp')
12     pass
13 
14 
15 if __name__ == '__main__':
16     session = get_start_session()
17     get_base_cookies(session)

進行斷點調試並輸出:

 接着:下載驗證碼圖片(在當前的目錄下新建一個img文件夾用來保存圖片)

1 def get_base_cookies(s):
2     response = s.get('https://user.qunar.com/passport/login.jsp')
3     get_image(s) #當即下載圖片
4 
5 def get_image(s):
6     response = s.get('https://user.qunar.com/captcha/api/image?k={en7mni(z&p=ucenter_login&c=ef7d278eca6d25aa6aec7272d57f0a9a')
7 
8     with open('code1.png' , 'wb') as f:
9         f.write(response.content)

輸出:

接着:嘗試錯誤登陸,此次咱們使用正確的驗證碼

 1 #定義登陸函數
 2 def login(s,username,password,code): #使用session發送請求,方便合併cookies,並傳入參數
 3 
 4     data = {
 5         'loginType': 0,
 6         'username': username,
 7         'password': password,
 8         'remember': 1,
 9         'vcode': code,
10     }
11 
12     url = 'https://user.qunar.com/passport/login.jsp'
13 
14 
15     response = s.post(url ,data = data ) #這裏咱們使用post發送請求

 最後:結合chrome補全cookies參數,這裏咱們只需保存有用的cookie便可

 1 def get_base_cookies(s):
 2     s.get('https://user.qunar.com/passport/login.jsp')
 3     get_image(s)
 4     s.get('https://user.qunar.com/passport/addICK.jsp?ssl')
 5     response = s.get('https://rmcsdf.qunar.com/js/df.js?org_id=ucenter.login&js_type=0')
 6 
 7     #獲取sessionid
 8     session_id = re.findall(r'sessionId=(.*?)&',response.text)
 9     session_id = session_id[0]  #脫殼操做
10 
11     #獲取fid
12     s.get('https://rmcsdf.qunar.com/api/device/challenge.json?callback=callback_1527735086394&sessionId={}&domain=qunar.com&orgId=ucenter.login'.format(session_id))
13     s.cookies.update({'QN271':session_id})

(3)、完整代碼

 1 #author: "xian"
 2 #date: 2018/5/30
 3 import re
 4 import requests
 5 
 6 #使用requests庫的會話維持用法
 7 def start_get_session():
 8     s = requests.session()
 9     return s
10 
11 def get_base_cookies(s):
12     s.get('https://user.qunar.com/passport/login.jsp')
13     get_image(s)
14     s.get('https://user.qunar.com/passport/addICK.jsp?ssl')
15     response = s.get('https://rmcsdf.qunar.com/js/df.js?org_id=ucenter.login&js_type=0')
16 
17     #獲取sessionid
18     session_id = re.findall(r'sessionId=(.*?)&',response.text)
19     session_id = session_id[0]  #脫殼操做
20 
21     #獲取fid
22     s.get('https://rmcsdf.qunar.com/api/device/challenge.json?callback=callback_1527735086394&sessionId={}&domain=qunar.com&orgId=ucenter.login'.format(session_id)) 
23 s.cookies.update({'QN271':session_id})
25
26
27
28 #獲取圖片
29 def get_image(s):
30   response = s.get('https://user.qunar.com/captcha/api/image?k={en7mni(z&p=ucenter_login&c=ef7d278eca6d25aa6aec7272d57f0a9a&t=1527644979725') 
31
32
33  with open('./img/code.png','wb') as f:
34   f.write(response.content)
35
36
37 #登陸函數
38 def login(s,username,password,code):
39   data = {
40   'loginType': 0,
41   'username': username,
42   'password': password,
43   'remember': 1,
44   'vcode': code,
45    }
46
47   url = 'https://user.qunar.com/passport/loginx.jsp'
48   response = s.post(url,data = data)
49   print(response.text)
50   response = s.get('http://user.qunar.com/index/basic')
#模擬登陸後爬取該網頁
51   print(response.text)
52
53
54
55
#主函數
56 if __name__ == '__main__':
57   session = start_get_session()
58   get_base_cookies(session)
59   username = input('請輸入用戶名:')
60   password = input('請輸入密碼:')
61   code = input('請輸入驗證碼:')
62
63   login(session,username,password,code)

運行效果圖:

相關文章
相關標籤/搜索