摘要:這里不討論用的情況,僅僅以來說明模擬登陸先嘗試用真實瀏覽器登陸,登陸成功后在開發者工具的選項卡中捕獲文件。
這里不討論用 Github API 的情況,僅僅以 Github 來說明模擬登陸
先嘗試用真實瀏覽器登陸,登陸成功后在開發者工具的 Network 選項卡中捕獲 Session 文件。可以看到,登陸所需要的數據不僅僅是 email(或用戶名) 和密碼,還需要其它的 3 個字段,而這 3 個字段普通用戶在真實瀏覽器中是無法填寫的(也無需填寫,這仨字段會自動附加到表單中提交)。
其中的 commit、utf8 的值是不變的,只有 authenticity_token 字段的值是每次登陸都不一樣的(為的就是區分人類與爬蟲程序),authenticity_token 字段是在 https://github.com/login (登陸頁面,未登陸狀態)的 from 元素下的一個隱含字段(不顯示在瀏覽器中),其 type 屬性值為 hidden。
下圖展示了(重新)登陸頁面的源碼,其中 type 屬性為 hidden 的 input 字段中的 authenticity_token 屬性的值就是需要提取出來作為表單數據的一部分提交至服務器
從下圖可以看到響應碼(Status Code)是 302 found 表示重定向跳轉至其它 url,這里跳轉至 https://github.com,也就是說,登陸成功后就跳轉至 Github 首頁(即個人主頁)
雖然是在 https://github.com/login 頁面中登陸,但登陸時是向 https://github.com/session 提交表單數據,所以在 session 響應中可惜查看到已提交的表單數據。
上圖展示了登陸成功后,已提交的表單數據,可以發現 authenticity_token 字段的值和登陸前的值是一致的(email、password 字段由于是明文,所以這里打碼了)
能保持登陸狀態的原因是登陸成功后生成 Cookies 的功勞,不過 Cookies 一般不是永久有效的,如果希望長期處于登陸狀態,需要每隔一段時間檢測下 Cookies 是否還有效(或進行異常處理),失效的話就需要重新提交表單生成新的 Cookies。
代碼實現使用的庫
requests
pyquery
攜帶 Cookies 模擬登陸 Github 的例子代碼中的表單數據 post_data 的 login、password 這倆字段分別需要改為自已的 email(或用戶名)及密碼
import requests from pyquery import PyQuery as pq headers = { "Referer": "https://github.com/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36", "Host": "github.com", } login_url = "https://github.com/login" post_url = "https://github.com/session" logined_url = "https://github.com/settings/profile" keys_url = "https://github.com/settings/keys" # 提取隱含字段 authenticity_token 的值,登陸需要提交表單,而提交表單需要該值 login_r = requests.get(login_url, headers=headers) doc = pq(login_r.text) token = doc("input[name="authenticity_token"]").attr("value").strip() print(token) # 構造表單數據 post_data = { "commit": "Sign in", "utf8": "?", "authenticity_token": token, "login": email_or_name, "password": password, } # 模擬登陸必須攜帶 Cookies post_r = requests.post(post_url, data=post_data, headers=headers, cookies=login_r.cookies.get_dict()) # 可以發現響應的 url 是 https://github.com,而不是 https://github.com/session # 因為模擬登陸成功后就 302 重定向跳轉至 "https://github.com" 了 print(post_r.url) doc = pq(post_r.text) # 輸出項目列表 print(doc("div.Box-body > ul > li").text().split()) # 請求其它 github 頁面,只要附加了能維持登陸狀態的 Cooikes 就可以訪問只有登陸才可訪問的頁面內容 logined_r = requests.get(logined_url, headers=headers, cookies=post_r.cookies.get_dict()) doc = pq(logined_r.text) page_title = doc("title").text() user_profile_bio = doc("#user_profile_bio").text() user_profile_company = doc("#user_profile_company").attr("value") user_profile_location = doc("#user_profile_location").attr("value") print(f"頁面標題:{page_title}") print(f"用戶資料描述:{user_profile_bio}") print(f"用戶資料公司:{user_profile_company}") print(f"用戶資料地點:{user_profile_location}") # 使用 logined_r 的 Cookies 也可以 keys_r = requests.get(keys_url, headers=headers, cookies=post_r.cookies.get_dict()) doc = pq(keys_r.text) # SSH keys Title doc("#ssh-key-29454773 strong.d-block").text()
顯式傳入 Cookies 、headers 還是挺麻煩的,萬一有個請求沒有攜帶完整的 Cookies,可能就無法得到正確的響應。
為了省略每次都要手動傳入 Cookies 的麻煩,下面使用另一種方式模擬登陸 Github
利用 Session 對象維持 Github 模擬登陸狀態構造一個 session 對象;
使用 session 對象進行請求
代碼其中使用 session.headers 維持每次會話的 headers 不變
為了安全,利用內置模塊 getpass 輸入不可見的密碼(注意密碼一定不能錯)
import getpass import requests from pyquery import PyQuery as pq class Login(object): def __init__(self): base_url = "https://github.com/" # 登陸 url self.login_url = base_url +"login" # 提交表單的 api self.post_url = base_url +"session" # 個人資料頁面的 url self.logined_url = base_url +"settings/profile" # 構造一個會話對象 self.session = requests.Session() # 自定義請求頭 self.session.headers = { "Referer": "https://github.com/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36", "Host": "github.com" } def token(self): # 請求登陸頁面 response = self.session.get(self.login_url) # 提取 authenticity_token 的 value, doc = pq(response.text) token = doc("input[name="authenticity_token"]").attr("value").strip() return token def login(self, email, password): token = self.token() # 構造表單數據 post_data = { "commit": "Sign in", "utf8": "?", "authenticity_token": token, "login": email, "password": password } # 發送 POST 請求,它會 302 重定向至 "https://github.com/",也就是響應 "https://github.com/" 的頁面 response = self.session.post(self.post_url, data=post_data) # 可以發現 302 重定向至 "https://github.com/" print(f" 請求 url:{response.url}") if response.status_code == 200: print("status_code: 200") self.home(response.text) # 請求個人資料頁 response = self.session.get(self.logined_url) if response.status_code == 200: print("status_code: 200") self.profile(response.text) def home(self, html): doc = pq(html) # 提取用戶名 user_name = doc("summary > span").text().strip() print(f"用戶名:{user_name}") # 提取倉庫列表 Repositories = doc("div.Box-body > ul > li").text().split() for Repositorie in Repositories: print(Repositorie) def profile(self, html): doc = pq(html) page_title = doc("title").text() user_profile_bio = doc("#user_profile_bio").text() user_profile_company = doc("#user_profile_company").attr("value") user_profile_location = doc("#user_profile_location").attr("value") print(f"頁面標題:{page_title}") print(f"用戶資料描述:{user_profile_bio}") print(f"用戶資料公司:{user_profile_company}") print(f"用戶資料地點:{user_profile_location}") def main(self): email = input("email or username: ") # 輸入的密碼不可見,注意密碼一定不能錯 password = getpass.getpass("password:") self.login(email=email, password=password) if __name__ == "__main__": login = Login() login.main()
本文參考 《Python 3 網絡爬蟲開發實戰》 —— 10.1 模擬登陸并爬取 GitHub
隱含字段參考了 《Python網絡數據采集》 —— 12.3 常見表單安全措施
閱讀更多字符圖像識別——數字字母混合
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/42266.html
摘要:微信知乎新浪等主流網站的模擬登陸爬取方法摘要微信知乎新浪等主流網站的模擬登陸爬取方法。先說說很難爬的知乎,假如我們想爬取知乎主頁的內容,就必須要先登陸才能爬,不然看不到這個界面。圖片描述知乎需要手機號才能注冊登陸。 微信、知乎、新浪等主流網站的模擬登陸爬取方法摘要:微信、知乎、新浪等主流網站的模擬登陸爬取方法。 網絡上有形形色色的網站,不同類型的網站爬蟲策略不同,難易程度也不一樣。從是...
摘要:可能有的老手覺得我寫得很啰嗦,但其實很多新手可能都不知道這些細節,所以我把我在分析新浪微博模擬登陸的過程全寫了出來。 這篇文章于去年4月發布在我的簡書,現在把它放到這里,主要是為了宣傳自己的分布式微博爬蟲。下面是主要內容,希望能幫到有這個需求的朋友 最近由于需要一直在研究微博的爬蟲,第一步便是模擬登陸,從開始摸索到走通模擬登陸這條路其實還是挺艱難的,需要一定的經驗,為了讓朋友們以后少...
摘要:在抓取數據之前,請在瀏覽器中登錄過知乎,這樣才使得是有效的。所謂的模擬登陸,只是在中盡量的模擬在瀏覽器中的交互過程,使服務端無感抓包過程。若是幫你解決了問題,或者給了你啟發,不要吝嗇給加一星。 折騰了將近兩天,中間數次想要放棄,還好硬著頭皮搞下去了,在此分享出來,希望有同等需求的各位能少走一些彎路。 源碼放在了github上, 歡迎前往查看。 若是幫你解決了問題,或者給了你啟發,不要吝...
摘要:我們這次模擬登陸成功的標志就是拿到登陸后的和,有過期時間,我稍微測試了下大概有個小時左右。因為微信公眾平臺老是跳轉刷新,所以很難找到請求的網址和接口。分析結果的過程不難,照著登陸流程走,反復調試就可以。 聲明此代碼僅供技術交流學習,擅自用于其他,一切后果與本人無關 目標網址: https://mp.weixin.qq.com/ 所謂模擬登陸,就是自己模擬構造請求發送給服務器,然后服務器...
摘要:大致意思是模擬登陸,一時手癢,本文將帶領大家一起實現這個操作。方案事實上為了探究這個有意思的問題,我專門動手做一個有意思的實驗。這說明了服務端驗證了輸入,并判斷我們的請求不符合正常邏輯。過程不再贅述,結果是中的必須和中的對應。 前言 本文來自我在 SegmentFault 上的 回答,我紀錄了其中精彩的部分到本博客。 大致意思是模擬登陸 segmentfault.com,一時手癢,本文...
閱讀 3603·2021-11-24 10:25
閱讀 2508·2021-11-24 09:38
閱讀 1217·2021-09-08 10:41
閱讀 2903·2021-09-01 10:42
閱讀 2569·2021-07-25 21:37
閱讀 1981·2019-08-30 15:56
閱讀 914·2019-08-30 15:55
閱讀 2749·2019-08-30 15:54