成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

模擬登陸Github

phodal / 1195人閱讀

摘要:這里不討論用的情況,僅僅以來說明模擬登陸先嘗試用真實(shí)瀏覽器登陸,登陸成功后在開發(fā)者工具的選項(xiàng)卡中捕獲文件。

這里不討論用 Github API 的情況,僅僅以 Github 來說明模擬登陸

先嘗試用真實(shí)瀏覽器登陸,登陸成功后在開發(fā)者工具的 Network 選項(xiàng)卡中捕獲 Session 文件??梢钥吹?,登陸所需要的數(shù)據(jù)不僅僅是 email(或用戶名) 和密碼,還需要其它的 3 個(gè)字段,而這 3 個(gè)字段普通用戶在真實(shí)瀏覽器中是無法填寫的(也無需填寫,這仨字段會(huì)自動(dòng)附加到表單中提交)。

其中的 commit、utf8 的值是不變的,只有 authenticity_token 字段的值是每次登陸都不一樣的(為的就是區(qū)分人類與爬蟲程序),authenticity_token 字段是在 https://github.com/login (登陸頁面,未登陸狀態(tài))的 from 元素下的一個(gè)隱含字段(不顯示在瀏覽器中),其 type 屬性值為 hidden。

下圖展示了(重新)登陸頁面的源碼,其中 type 屬性為 hidden 的 input 字段中的 authenticity_token 屬性的值就是需要提取出來作為表單數(shù)據(jù)的一部分提交至服務(wù)器

從下圖可以看到響應(yīng)碼(Status Code)是 302 found 表示重定向跳轉(zhuǎn)至其它 url,這里跳轉(zhuǎn)至 https://github.com,也就是說,登陸成功后就跳轉(zhuǎn)至 Github 首頁(即個(gè)人主頁)

雖然是在 https://github.com/login 頁面中登陸,但登陸時(shí)是向 https://github.com/session 提交表單數(shù)據(jù),所以在 session 響應(yīng)中可惜查看到已提交的表單數(shù)據(jù)。

上圖展示了登陸成功后,已提交的表單數(shù)據(jù),可以發(fā)現(xiàn) authenticity_token 字段的值和登陸前的值是一致的(email、password 字段由于是明文,所以這里打碼了)

能保持登陸狀態(tài)的原因是登陸成功后生成 Cookies 的功勞,不過 Cookies 一般不是永久有效的,如果希望長(zhǎng)期處于登陸狀態(tài),需要每隔一段時(shí)間檢測(cè)下 Cookies 是否還有效(或進(jìn)行異常處理),失效的話就需要重新提交表單生成新的 Cookies。

代碼實(shí)現(xiàn)

使用的庫(kù)

requests

pyquery

攜帶 Cookies 模擬登陸 Github 的例子

代碼中的表單數(shù)據(jù) 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)

# 構(gòu)造表單數(shù)據(jù)
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())
# 可以發(fā)現(xiàn)響應(yīng)的 url 是 https://github.com,而不是 https://github.com/session
# 因?yàn)槟M登陸成功后就 302 重定向跳轉(zhuǎn)至 "https://github.com" 了
print(post_r.url)
doc = pq(post_r.text)
# 輸出項(xiàng)目列表
print(doc("div.Box-body > ul > li").text().split())

# 請(qǐng)求其它 github 頁面,只要附加了能維持登陸狀態(tài)的 Cooikes 就可以訪問只有登陸才可訪問的頁面內(nèi)容
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"頁面標(biāo)題:{page_title}")
print(f"用戶資料描述:{user_profile_bio}")
print(f"用戶資料公司:{user_profile_company}")
print(f"用戶資料地點(diǎn):{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 還是挺麻煩的,萬一有個(gè)請(qǐng)求沒有攜帶完整的 Cookies,可能就無法得到正確的響應(yīng)。

為了省略每次都要手動(dòng)傳入 Cookies 的麻煩,下面使用另一種方式模擬登陸 Github

利用 Session 對(duì)象維持 Github 模擬登陸狀態(tài)

構(gòu)造一個(gè) session 對(duì)象;

使用 session 對(duì)象進(jìn)行請(qǐng)求

代碼

其中使用 session.headers 維持每次會(huì)話的 headers 不變

為了安全,利用內(nèi)置模塊 getpass 輸入不可見的密碼(注意密碼一定不能錯(cuò))

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"
        # 個(gè)人資料頁面的 url
        self.logined_url = base_url +"settings/profile"
        # 構(gòu)造一個(gè)會(huì)話對(duì)象
        self.session = requests.Session()
        # 自定義請(qǐng)求頭
        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):
        # 請(qǐng)求登陸頁面
        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()
        # 構(gòu)造表單數(shù)據(jù)
        post_data = {
            "commit": "Sign in",
            "utf8": "?",
            "authenticity_token": token,
            "login": email,
            "password": password
        }
        # 發(fā)送 POST 請(qǐng)求,它會(huì) 302 重定向至 "https://github.com/",也就是響應(yīng) "https://github.com/" 的頁面
        response = self.session.post(self.post_url, data=post_data)
        # 可以發(fā)現(xiàn) 302 重定向至 "https://github.com/"
        print(f"
請(qǐng)求 url:{response.url}")
        if response.status_code == 200:
            print("status_code: 200")
            self.home(response.text)

        # 請(qǐng)求個(gè)人資料頁
        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}")

        # 提取倉(cāng)庫(kù)列表        
        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"頁面標(biāo)題:{page_title}")
        print(f"用戶資料描述:{user_profile_bio}")
        print(f"用戶資料公司:{user_profile_company}")
        print(f"用戶資料地點(diǎn):{user_profile_location}")

    def main(self):
        email = input("email or username: ")
        # 輸入的密碼不可見,注意密碼一定不能錯(cuò)
        password = getpass.getpass("password:")
        self.login(email=email, password=password)

if __name__ == "__main__":
    login = Login()
    login.main()
運(yùn)行效果

參考資料

本文參考 《Python 3 網(wǎng)絡(luò)爬蟲開發(fā)實(shí)戰(zhàn)》 —— 10.1 模擬登陸并爬取 GitHub

隱含字段參考了 《Python網(wǎng)絡(luò)數(shù)據(jù)采集》 —— 12.3 常見表單安全措施

閱讀更多

字符圖像識(shí)別——數(shù)字字母混合

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42266.html

相關(guān)文章

  • Python爬蟲學(xué)習(xí):微信、知乎、新浪等主流網(wǎng)站的模擬登陸爬取方法

    摘要:微信知乎新浪等主流網(wǎng)站的模擬登陸爬取方法摘要微信知乎新浪等主流網(wǎng)站的模擬登陸爬取方法。先說說很難爬的知乎,假如我們想爬取知乎主頁的內(nèi)容,就必須要先登陸才能爬,不然看不到這個(gè)界面。圖片描述知乎需要手機(jī)號(hào)才能注冊(cè)登陸。 微信、知乎、新浪等主流網(wǎng)站的模擬登陸爬取方法摘要:微信、知乎、新浪等主流網(wǎng)站的模擬登陸爬取方法。 網(wǎng)絡(luò)上有形形色色的網(wǎng)站,不同類型的網(wǎng)站爬蟲策略不同,難易程度也不一樣。從是...

    Kahn 評(píng)論0 收藏0
  • 超詳細(xì)的Python實(shí)現(xiàn)新浪微博模擬登陸(小白都能懂)

    摘要:可能有的老手覺得我寫得很啰嗦,但其實(shí)很多新手可能都不知道這些細(xì)節(jié),所以我把我在分析新浪微博模擬登陸的過程全寫了出來。 這篇文章于去年4月發(fā)布在我的簡(jiǎn)書,現(xiàn)在把它放到這里,主要是為了宣傳自己的分布式微博爬蟲。下面是主要內(nèi)容,希望能幫到有這個(gè)需求的朋友 最近由于需要一直在研究微博的爬蟲,第一步便是模擬登陸,從開始摸索到走通模擬登陸這條路其實(shí)還是挺艱難的,需要一定的經(jīng)驗(yàn),為了讓朋友們以后少...

    Aldous 評(píng)論0 收藏0
  • scrapy模擬登陸知乎--抓取熱點(diǎn)話題

    摘要:在抓取數(shù)據(jù)之前,請(qǐng)?jiān)跒g覽器中登錄過知乎,這樣才使得是有效的。所謂的模擬登陸,只是在中盡量的模擬在瀏覽器中的交互過程,使服務(wù)端無感抓包過程。若是幫你解決了問題,或者給了你啟發(fā),不要吝嗇給加一星。 折騰了將近兩天,中間數(shù)次想要放棄,還好硬著頭皮搞下去了,在此分享出來,希望有同等需求的各位能少走一些彎路。 源碼放在了github上, 歡迎前往查看。 若是幫你解決了問題,或者給了你啟發(fā),不要吝...

    leanxi 評(píng)論0 收藏0
  • Python3微信公眾平臺(tái)requests模擬登陸

    摘要:我們這次模擬登陸成功的標(biāo)志就是拿到登陸后的和,有過期時(shí)間,我稍微測(cè)試了下大概有個(gè)小時(shí)左右。因?yàn)槲⑿殴娖脚_(tái)老是跳轉(zhuǎn)刷新,所以很難找到請(qǐng)求的網(wǎng)址和接口。分析結(jié)果的過程不難,照著登陸流程走,反復(fù)調(diào)試就可以。 聲明此代碼僅供技術(shù)交流學(xué)習(xí),擅自用于其他,一切后果與本人無關(guān) 目標(biāo)網(wǎng)址: https://mp.weixin.qq.com/ 所謂模擬登陸,就是自己模擬構(gòu)造請(qǐng)求發(fā)送給服務(wù)器,然后服務(wù)器...

    alogy 評(píng)論0 收藏0
  • 爬蟲模擬登陸 SegmentFault

    摘要:大致意思是模擬登陸,一時(shí)手癢,本文將帶領(lǐng)大家一起實(shí)現(xiàn)這個(gè)操作。方案事實(shí)上為了探究這個(gè)有意思的問題,我專門動(dòng)手做一個(gè)有意思的實(shí)驗(yàn)。這說明了服務(wù)端驗(yàn)證了輸入,并判斷我們的請(qǐng)求不符合正常邏輯。過程不再贅述,結(jié)果是中的必須和中的對(duì)應(yīng)。 前言 本文來自我在 SegmentFault 上的 回答,我紀(jì)錄了其中精彩的部分到本博客。 大致意思是模擬登陸 segmentfault.com,一時(shí)手癢,本文...

    bovenson 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<