模擬登錄Github

1. 檢查請求

首先來到Github的登錄頁面,如下所示。


image.png

然后打開開發(fā)者模式,切換到Netword選項(xiàng)卡下,然后在瀏覽器輸入用戶名和密碼,不要著急點(diǎn)擊登錄,先清除Network下的所有請求。
然后點(diǎn)擊登錄,會(huì)看到有很多的請求被發(fā)送出去。
接著找到第一個(gè)session請求,查看該post請求的form data,如下圖所示。


Form data

其中的login 和 password就是我們所輸入的賬號名與密碼。那么,接下來的模擬過程就是我們只需要構(gòu)造這個(gè)form data然后往該請求的request URL發(fā)送數(shù)據(jù)就可以完成模擬登錄。
經(jīng)過分析可以發(fā)現(xiàn),我們需要構(gòu)造的參數(shù)有authenticity_token,ga_id , timestamp,timestamp_secret這四個(gè)參數(shù),其他的例如commit ,utf8,webauth-invpaa-support 等可以直接復(fù)制。

2.構(gòu)造請求參數(shù)

那么,我們要怎樣構(gòu)造所需要的四個(gè)參數(shù)呢?

2.1 authenticity_token

我們還是在登錄頁面打開開發(fā)者模式,不用輸入賬戶密碼進(jìn)行登錄,然后切換到Element選項(xiàng)下,在該頁面下搜索token,發(fā)現(xiàn)只有一個(gè)搜索結(jié)果。


token

這個(gè)input元素里的value值就是authenticity_token的值,我們只需通過xpath選擇器選擇該節(jié)點(diǎn),然后取其value屬性即可。該xpath表達(dá)式為://input[@name="authenticity_token"]/@value

2.2 timestamp與timestamp_secret

同樣,我們搜索timestamp可以同時(shí)發(fā)現(xiàn)timestamp與tiemstamp_secret兩個(gè)參數(shù)。


timestamp&timestamp_secret

其value值也就是我們需要的參數(shù)值。
然后通過xpath選出該值。
timestamp://input[@name="timestamp"]/@value
timestamp_secret://input[@name="timestamp_secret"]/@value

2.3 ga_id

跟上面的思路一樣,我們可以通過同樣的方式找出ga_id,一共有兩個(gè)搜索結(jié)果,一個(gè)是head 里的meta信息,還有一個(gè)是登錄表單里的信息。


head-->meta

input

這兩個(gè)元素里都有我們需要的值,meta里的content內(nèi)容和inp里的value值就是ga_id 的值,而且這兩個(gè)值是一樣的。照理,我們也可以用xpath提取到ga_id的值。但是在程序完成之后,我們發(fā)現(xiàn)其他的值都可以提取出來,而ga_id提取的出來的值卻為空,其原因是該元素是通過js動(dòng)態(tài)加載的,在程序里是提取不到這個(gè)值的。所以,在這個(gè)地方我們有兩種解決辦法,一個(gè)是閱讀js的代碼,找到ga_id的生成方法后自己生成一個(gè)ga_id,還有一種是通過Selenium加載頁面,然后按照xpath提取值。在這里我們選用第二種方法,因?yàn)檫@種方法快速簡潔而方便。

    def ga_id(self):
        broser = webdriver.Chrome()
        broser.get(self.login_url)
        time.sleep(5)
        html = broser.page_source
        html = etree.HTML(html)
        ga_id = html.xpath('//div//input[@name="ga_id"]/@value')[0]
        return ga_id

這里要用Chrome驅(qū)動(dòng),用Phantomjs驅(qū)動(dòng)依然提取不到值。
這樣,我們需要的請求參數(shù)都構(gòu)造完成了,接下來發(fā)送請求就可以了。

3.發(fā)送請求

    def login(self):
        formdata = {
            'commit':'Sign in',
            'utf8':'√',
            'authenticity_token':self.token(),
            'ga_id':self.ga_id(),
            'login':賬號名,
            'password':密碼,
            'webauthn-support':'',
            'webauthn-iuvpaa-support':'',
            'timestamp':self.timestamp(),
            'timestamp_secret':self.timestamp_secret()

        }
        response = self.session.post(self.post_url,data=formdata,headers=self.headers)

        # 測試登錄后的頁面
        zhuye = self.session.get('https://github.com/settings/keys',headers =self.headers)
        print(zhuye.text)

運(yùn)行代碼可以發(fā)現(xiàn)其輸出了登錄后才能顯示的頁面,也就模擬登錄成功了。

完整代碼如下:

# coding-utf-8
import time
import requests
from lxml import etree
from selenium import webdriver

class Login(object):
    def __init__(self):
        self.headers = {
            "Origin":"https://github.com",
            "Host":"github.com",
            "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0"
        }
        self.login_url = "https://github.com/login"
        self.post_url = "https://github.com/session"
        self.session = requests.Session()

        self.lresponse = self.session.get(self.login_url, headers=self.headers)
        self.html = etree.HTML(self.lresponse.text)


    def token(self):
        token = self.html.xpath('//input[@name="authenticity_token"]/@value')[0]
        return token

    def ga_id(self):
        broser = webdriver.Chrome()
        broser.get(self.login_url)
        time.sleep(5)
        html = broser.page_source
        html = etree.HTML(html)
        ga_id = html.xpath('//div//input[@name="ga_id"]/@value')[0]
        return ga_id

    def timestamp(self):
        tiemstamp = self.html.xpath('//input[@name="timestamp"]/@value')[0]
        return tiemstamp

    def timestamp_secret(self):
        tiemstamp_secret = self.html.xpath('//input[@name="timestamp_secret"]/@value')[0]
        return tiemstamp_secret

    def login(self):
        formdata = {
            'commit':'Sign in',
            'utf8':'√',
            'authenticity_token':self.token(),
            'ga_id':self.ga_id(),
            'login':賬號,
            'password':密碼,
            'webauthn-support':'',
            'webauthn-iuvpaa-support':'',
            'timestamp':self.timestamp(),
            'timestamp_secret':self.timestamp_secret()

        }
        response = self.session.post(self.post_url,data=formdata,headers=self.headers)

        # 測試登錄后的頁面
        zhuye = self.session.get('https://github.com/settings/keys',headers =self.headers)
        print(zhuye.text)

if __name__ =="__main__":
    github = Login()
    github.login()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容