Python爬蟲學習筆記之模擬登錄並爬去GitHub

(1)環境準備:html

        請確保已經安裝了requests和lxml庫git

(2)分析登錄過程:github

    首先要分析登錄的過程,須要探究後臺的登錄請求是怎樣發送的,登錄以後又有怎樣的處理過程。瀏覽器

     若是已經登錄GitHub,則須要先退出登錄,同時清除Cookiescookie

     打開GitHub的登錄頁面,連接爲https://github.com/login,輸入GitHub的用戶名和密碼,打開開發者工具session

     ,將Preserver Log選項勾選上,這表示持續日誌,以下圖所示函數

 

           點擊登陸按鈕,這時便會看到開發者工具下方顯示了各個請求過程,以下圖所示:工具

 

     點擊session請求,進入其詳情,以下圖所示:post

 

      能夠看到請求的URL爲https://www.github.com/session,請求方式爲POST。再往下看,咱們觀察到他的Form Data和Headers這兩部份內容,加密

   以下圖所示:

     Headers裏面包含了Cookies,Host,Origin,Refer,User-Agent等信息。Form Data包含了5個字段,commit是固定的字符串Sign in,utf8

是一個勾選字符,authenticity_token較長,其初步判斷是一個Base64加密的字符串,login是登錄的用戶名,password是登錄的密碼。

     綜上所述,咱們如今沒法直接構造的內容有Cookies和authenticity_token。下面咱們再來探尋一下這部份內容如何獲取。

在登錄以前咱們會訪問到一個登錄頁面,此頁面是經過GET形式訪問的。輸入用戶名和密碼,點擊登陸按鈕,瀏覽器發送這兩部分信息,也就是

說Cookies和authenticity_token必定在訪問扥估頁面時候設置的。

     這時在退出登錄,回到登陸頁,同時清除Cookies,從新訪問登陸頁,截獲發生的請求,以下圖所示:

   

     訪問登錄頁面的請求如上,Response Headers有一個Set-Cookie字段。這就是設置Cookies的過程。

     另外,咱們發現Response Headers沒有和authenticity_token相關的信息,因此可能authenticity_token還隱藏在其餘的地方或者是計算出來的

。咱們再從網頁的源碼探尋,搜索相關字段,發現源代碼裏面還隱藏着此信息,他是一個隱藏式表單元素,以下圖所示:

 

     如今咱們已經獲取到網頁全部信息,接下來讓咱們 實現模擬登錄

(3)代碼以下:

 1 import requests
 2 from lxml import etree
 3 
 4 class Login(object):
 5     def __init__(self):
 6         self.headers = {
 7             'Refer': 'https://github.com',
 8             'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
 9                           'Chrome/68.0.3440.75 Safari/537.36',
10             'Host': 'github.com'
11         }
12         self.login_url = 'https://github.com/login'
13         self.post_url = 'https://github.com/session'
14         self.logined_url = 'https://github.com/settings/profile'
15         self.session = requests.Session()   # 此函數能夠幫助咱們維持一個會話,並且能夠自動處理cookies,咱們不用再去擔憂cookies的問題
16 
17     def token(self):
18         response = self.session.get(self.login_url, headers=self.headers)  # 訪問GitHub的登陸頁面
19         selector = etree.HTML(response.text)
20         token = selector.xpath('//div//input[2]/@value')[0]   # 解析出登錄所需的authenticity_token信息
21         return token
22 
23     def login(self, email, password):
24         post_data = {
25             'commit': 'Sign in',
26             'utf-8': '',
27             'authenticity_token': self.token(),
28             'login': email,
29             'password': password
30         }
31         response = self.session.post(self.post_url, data=post_data, headers=self.headers)
32         if response.status_code == 200:
33             self.dynamics(response.text)
34 
35         response = self.session.get(self.logined_url, headers=self.headers)
36         if response.status_code == 200:
37             self.profile(response.text)
38 
39     def dynamics(self, html):  # 使用此方法提取全部動態信息
40         selector = etree.HTML(html)
41         dynamics = selector.xpath('//div[contains(@class, "news")]//div[contains(@class, "alert")]')
42         for item in dynamics:
43             dynamics = ' '.join(item.xpath('.//div[@class="title"]//text()')).strip()
44             print(dynamics)
45 
46     def profile(self, html):  # 使用此方法提取我的的暱稱和綁定的郵箱
47         selector = etree.HTML(html)
48         name = selector.xpath('//input[@id="user_profile_name"]/@value')[0]
49         email = selector.xpath('//select[@id="user_profile_email"]/option[@value!=""]/text()')
50         print(name, email)
51 
52 if __name__ == "__main__":
53     login = Login()
54     login.login(email='', password='')  # 此處填本身的
相關文章
相關標籤/搜索