互聯網上的部分網站須要登陸後方能訪問,當咱們打開網頁並登陸,就會在客戶端生成Cookies(至關於我的身份證)信息,Cookies中包含了SessionId信息,登陸後的請求都會帶上Cookies發送給服務器,服務器會根據Cookies判斷出對應的SessionID,進而找到會話,從而判斷用戶是否師登陸狀態,從而是否給用戶響應。html
答:讓機器模擬人在瀏覽器上的行爲登陸網站chrome
一、使用虛擬的瀏覽器json
步驟:請求登陸頁面的url----分析html中的表單數據----找到用戶名和密碼的輸入框----輸入本身的用戶名和密碼---模擬點擊登陸按鈕便可api
二、分析登陸信息提交方式,利用瀏覽器cookie模擬登陸瀏覽器
步驟:分析網頁結構,確認登陸方式,如帳號密碼登陸或掃碼登陸----如是帳號密碼登陸,確認有無驗證碼及驗證碼接口----進行錯誤登陸嘗試,觀察登陸系統的傳碼方案,如帳號密碼是否加密,是否有加密,是否有額外參數須要尋找,登陸須要傳入的cookie---根據錯誤登陸的分析結果,尋找額外的參數和須要傳入的cookie來源和密碼加密函數---反覆測試並編寫代碼服務器
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)
運行效果圖: