requests請求狀態保持-登入github為例
模擬登入-狀態保持
---- 以登入 github 為例
1 .頁面分析:
-
登入頁 ( https://github.com/login ) 網頁原始碼能找到 form 表單的提交方式是 post 請求,登入賬號並且開啟 Chrome 瀏覽器的除錯工具 ( F12 - Network - all ) 檢視提交請求,能到以下資訊
-
提交資料為:
commit: Sign in utf8: ✓ authenticity_token: UCGHpjglqtJ70hl/3ygpPUPVGLukUm0ACcYJ47BGb4pyyz6s+V5GHQSYQp419+EYcyUfJx3j/cGJziQonKIeAw== login: email password: passwd
其中 login 和 password 的引數值為使用者的郵箱和密碼,每個人不一樣。
分析 authenticity_token 這個引數值是沒有規律的,但是細心點會發現,在登入頁的網頁原始碼中的 form 標籤中有一個 type 為 "hidden" 並且 name 引數 為 "authenticity_token" 的 <input> 子標籤,其 value 引數值就是提交資料中的值。
-
2.流程說明
- 使用 requests.Session() 方法建立一個 Session 物件,這樣可以做到模擬同一個會話而不用擔心 Cookies 的問題。
- get 請求登入頁,xpath 解析出 "authenticity_token" 的值。為避免反爬,請加上請求頭 headers。
- 構建 post 請求,提交資料資料為上述的那些,請自行驗證其正確性。為避免反爬,請加上請求頭 headers。
- 登入成功後會自動重定向到首頁,此時已經做到了session 的狀態保持。
- 請求個人主頁解析自己的 使用者名稱 和 郵箱。(這一步只是測試。)
3.程式碼示例
-
demo版(面向流程)只是為了跑通流程,之後會改為物件導向版本。
import requests from lxml import etree # 登入頁get請求URL base_url = 'https://github.com/login' # 登入post提交URL login_url = 'https://github.com/session' # github個人主頁 profile_url = 'https://github.com/settings/profile' # 登入頁headers headers = { 'Referer':'https://github.com/', 'Host':'github.com', 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36', } # post 提交資料 post_data = { 'commit':'Sign in', 'utf8':'✓', 'login':'email@mail.com', 'password':'password', } # 保持會話式請求 s = requests.Session() # 請求登入頁獲取 token res_login = s.get(url=base_url, headers=headers) if res_login.status_code == requests.codes.ok: index_html = res_login.text index_html_obj = etree.HTML(index_html) # 獲取 authenticity_token,在post提交時會作為一個鍵值對傳入 token = index_html_obj.xpath('//div[@id="login"]/form/input[@name="authenticity_token"]/@value')[0] post_data['authenticity_token'] = token # 登入提交 res_index = s.post(url=login_url, headers=headers, data=post_data) if res_index.status_code == requests.codes.ok: print("登入成功,開始請求個人主頁") # 進入個人中心 res_profile = s.get(url=profile_url, headers=headers) if res_profile.status_code == requests.codes.ok: print("請求個人主頁成功,開始解析資料") profile_html = res_profile.text profile_obj = etree.HTML(profile_html) username = profile_obj.xpath('//div[@class="column two-thirds"]/dl[contains(@class,"form-group")]/dd/input[@id="user_profile_name"]/@value')[0] print("使用者名稱:", username) email = profile_obj.xpath('//div[@class="column two-thirds"]/dl[2]/dd/select/option[2]/text()')[0] print("郵箱:", email) else: print("請求個人主頁失敗") else: print("登入失敗")
-
物件導向版本
import requests from lxml import etree class GithubLogin(object): def __init__(self): # 登入頁get請求URL self.base_url = 'https://github.com/login' # 登入post提交URL self.login_url = 'https://github.com/session' # github個人主頁 self.profile_url = 'https://github.com/settings/profile' # 登入頁headers self.headers = { 'Referer': 'https://github.com/', 'Host': 'github.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36', } self.session = requests.Session() # 獲取登入頁的 authenticity_token 值 def token(self): res = self.session.get(url=self.base_url, headers=self.headers) if res.status_code == requests.codes.ok: res_obj = etree.HTML(res.text) token_value = res_obj.xpath('//div[@id="login"]/form/input[@name="authenticity_token"]/@value')[0] return token_value def login(self, email, passwd): post_data = { 'commit': 'Sign in', 'utf8': '✓', 'login': email, 'password': '753159wt', 'authenticity_token': self.token() } # 登入 post 提交表單 res_index = self.session.post(url=self.login_url, headers=self.headers, data=post_data) if res_index.status_code == requests.codes.ok: self.repository(res_index.text) # 請求個人中心頁面 res_profile = self.session.get(url=self.profile_url, headers=self.headers) if res_profile.status_code == requests.codes.ok: self.getProfile(res_profile.text) def repository(self, text): res_obj = etree.HTML(text) repo_list = res_obj.xpath('//div[@class="Box-body"]/ul/li//a/@href') for repo in repo_list: print(repo) def getProfile(self, text): res_obj = etree.HTML(text) username = res_obj.xpath('//div[@class="column two-thirds"]/dl[contains(@class,"form-group")]/dd/input[@id="user_profile_name"]/@value')[0] print("使用者名稱:", username) email = res_obj.xpath('//div[@class="column two-thirds"]/dl[2]/dd/select/option[2]/text()')[0] print("郵箱:", email) if __name__ == '__main__': alice_login = GithubLogin() alice_login.login('email@mail.com', 'password')
相關文章
- python+pytest介面自動化(9)-cookie繞過登入(保持登入狀態)PythonCookie
- 【開發必備】單點登入,清除了cookie,頁面還保持登入狀態?Cookie
- 網站http請求狀態碼網站HTTP
- requests模組 - get 請求
- requests 模組 - post 請求
- python requests get請求 如何獲取所有請求Python
- 模擬登陸——以github為例Github
- 爬蟲如何利用session方法保持登陸狀態(selenium)爬蟲Session
- Python中get、post請求詳解(HTTP請求頭、狀態碼)PythonHTTP
- 利用CSP探測網站登陸狀態(alipay/baidu為例)網站AI
- Vue外賣十一:登入成功資訊顯示、瀏覽器cookie+後端session登入狀態保持Vue瀏覽器Cookie後端Session
- 使用 requests 登入 learnku
- 請求更改狀態介面後,執行 sql 查出來狀態不對SQL
- HTTP狀態保持的原理HTTP
- PbootCMS登入請求發生錯誤boot
- status 返回當前請求的http狀態碼HTTP
- 傳送新請求,取消上一次pending狀態的同一請求
- 使用requests庫來傳送HTTP請求HTTP
- 4.爬蟲 requests庫講解 GET請求 POST請求 響應爬蟲
- 鴻蒙極速入門(六)-載入請求狀態管理-LoadState+觀察者模式鴻蒙模式
- 為爬蟲獲取登入cookies: 使用Charles和requests模擬微博登入爬蟲Cookie
- HTTP請求方法及響應狀態碼詳解HTTP
- vue帶參請求,登入時效(防止重複登陸)Vue
- 無法開啟登入所請求的資料庫,登入失敗資料庫
- python requests檢測響應狀態碼Python
- 模擬http或https請求,實現ssl下的bugzilla登入、新增BUG,保持會話以及處理tokenHTTP會話
- 視訊直播系統原始碼,登入平臺後在首頁保持長時間亮屏狀態原始碼
- 使⽤用Requests庫構建⼀一個HTTP請求HTTP
- requests請求返回內容 中文亂碼問題
- python-對requests請求簡單的封裝Python封裝
- 【網頁登入】QQ 登入、微信登入、微博登入、GitHub 登入網頁Github
- 請求OpenFeign的GET請求時,請求為何失敗?
- dubbo請求報文例項
- POS請求API介面樣例API
- Requests如何在Python爬蟲中實現get請求?Python爬蟲
- Python 之requests封裝通用http協議介面請求Python封裝HTTP協議
- Flutter 中如何保持Tabbar和TabbarView的狀態?FluttertabBarView
- 前端狀態管理簡易實現(以vuex為例)前端Vue