Python 爬蟲闖關(guān)(第三關(guān))

第三關(guān)開始有點難度了帆阳,本關(guān)的難點就是所謂的兩層認(rèn)證橱夭,需要獲取處理 cookie氨距。

闖關(guān)地址是:http://www.heibanke.com/lesson/crawler_ex02/

頁面分析

剛進入頁面時沒看懂是怎么玩,以為到這就結(jié)束了棘劣,抱著試試看的態(tài)度注冊了下俏让。

爬蟲闖關(guān) 第三關(guān)
爬蟲闖關(guān) 第三關(guān)

注冊登錄后,發(fā)現(xiàn)是一個記賬點之類的茬暇,網(wǎng)頁還沒有跳轉(zhuǎn)到題目網(wǎng)頁首昔,還不知道怎么玩。

重新從題目地址進入后糙俗,發(fā)現(xiàn)可以玩了:

題目頁面
題目頁面

頁面提示 比上一關(guān)多了兩層保護勒奇。

解題思路

題目中提到了兩層保護,是哪兩層呢巧骚?

首先赊颠,多了賬號登陸一層格二,還有一層是什么呢?重新登陸竣蹦,打開 firebug 記錄一下整個流程:

請求處理流程
請求處理流程

從動圖中我們可以看到整個流程分為 4 步顶猜,依次點擊 4 個步驟,分析記錄請求標(biāo)頭痘括、請求正文长窄、響應(yīng)標(biāo)頭、cookies 等是否有值纲菌,值為多少挠日,值的來源與請求順序之間的關(guān)系。

為了下文描述方便驰后,我們約定兩個變量:

  • URL=http://www.heibanke.com/lesson/crawler_ex02/
  • LOGIN_URL=http://www.heibanke.com/accounts/login/?next=/lesson/crawler_ex02/

第 1 步

首先訪問 URL肆资,瀏覽器會向 URL 發(fā)出 GET 請求矗愧,得到一個 302 的重定向的響應(yīng)灶芝,響應(yīng)標(biāo)頭中包含了一個 Location 字段,告訴瀏覽器新的訪問地址 LOGIN_URL唉韭。

如果之前用同樣的瀏覽器闖過第一關(guān)或第二關(guān)夜涕,此請求的請求標(biāo)頭仍然會帶上 cookie,但并無實際作用属愤,可忽略女器;

第 1 步
第 1 步

第 2 步

瀏覽器向 LOGIN_URL 發(fā)出新的 GET 請求。我們注意到請求和響應(yīng)中帶了一個 cookie住诸,其中都有一個 csrftoken 字段驾胆,其值為 708NMR2acyRWlblKw0rBqSjayL70TJDT。

如果仔細(xì)觀察贱呐,第一步請求頭的 cookie 中也有這么一個字段丧诺,我們將其記下,此 csrftoken 都將作為以后訪問過程中的依據(jù)之一奄薇。我們將此返回的 cookie 記為 c1驳阎;

第 2 步
第 2 步

第 3 步

首先我們這里已經(jīng)注冊過了,直接填寫登錄信息馁蒂,瀏覽器會再向 LOGIN_URL 發(fā)出 POST 請求呵晚,得到一個向第一步中 URL 的 重定向的 302 響應(yīng)。

請求標(biāo)頭和請求正文中都附帶上第二步中的 cookie c1沫屡,另外饵隙,我們發(fā)現(xiàn)請求正文參數(shù)中除了 username 和 password 字段外,還有一個 csrfmiddlewaretoken 字段沮脖,該字段的值就是 c1 中 csrftoken 的值金矛。

返回的響應(yīng)標(biāo)頭中附帶了兩個新的 cookie劫瞳,其中一個中同樣包含了 csrftoken 字段,值為 nmQXET2BHzNbhCksAur9XtLjEiYnfTC4绷柒,后面猜數(shù)字就會用到志于。我們將此返回的 cookies 記為 c2;

第 3 步
第 3 步
第 3 步
第 3 步

登錄成功后废睦,發(fā)現(xiàn)還是第二關(guān)的猜數(shù)字游戲伺绽。只不過,這次猜數(shù)字之前需要先進行登錄嗜湃,獲取 cookie奈应。

第 4 步

頁面填寫昵稱和數(shù)字,點擊提交购披,瀏覽器向 URL 提交 POST 請求杖挣,請求標(biāo)頭附帶的是第 3 步的 cookie c2,請求正文是昵稱密碼和 cookie c2 中的 csrftoken 對應(yīng)的值刚陡。

第 4 步
第 4 步
第 4 步請求正文
第 4 步請求正文

后面的步驟就和第二關(guān)差不多了惩妇,只不過需要帶上 cookie 和 csrftoken。

整個流程涉及兩次 cookie 的獲取筐乳,這就是題目所謂的兩層保護歌殃。

requests 實現(xiàn)

由于第 1 步返回結(jié)果中除了 Location 字段沒有其他有價值的信息,所以在已知新的地址的情況下可省略第 1 步蝙云,直接從第 2 步開始氓皱。

# coding=utf-8

import requests

url = 'http://www.heibanke.com/lesson/crawler_ex02/'

login_url = 'http://www.heibanke.com/accounts/login'

login_data = {'username':'liuhaha', 'password':'123456'}

# 獲取默認(rèn)cookie
response = requests.get(url)
if response.status_code == 200:
    print('Welcome')
cookies = response.cookies

# 登錄 
login_data['csrfmiddlewaretoken'] = cookies['csrftoken']
login_response = requests.post(login_url, allow_redirects=False, data=login_data, cookies=cookies)
if login_response.status_code == 200:
    print('login sucessfully')

# 獲取登錄成功后的cookie
cookies = login_response.cookies

playload = {'username':'liuhaha', 'password':'1'}
playload['csrfmiddlewaretoken'] = cookies['csrftoken']

for i in range(31):
    playload['password'] = i
    print(u'傳入?yún)?shù)為:' + str(playload))

    r = requests.post(url, data=playload, cookies=cookies)

    # print(u'執(zhí)行結(jié)果:' + str(r.status_code))

    if r.status_code == 200:
        if u"成功" in r.text:
            print(u'闖關(guān)成功!密碼為:' + str(i))
            break
    else:
        print(u'Failed')
        break

運行:

$ python crawler_ex02.1.py
Welcome
傳入?yún)?shù)為:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 0}
傳入?yún)?shù)為:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 1}
傳入?yún)?shù)為:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 2}
傳入?yún)?shù)為:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 3}
傳入?yún)?shù)為:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 4}
傳入?yún)?shù)為:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 5}
闖關(guān)成功勃刨!密碼為:5

使用 selenium 實現(xiàn)

使用 selenium 實現(xiàn)方式好像不涉及驗證之類的問題波材,因為完全是模擬的人類登錄瀏覽器的過程。

# coding=utf-8

from selenium import webdriver

url = 'http://www.heibanke.com/lesson/crawler_ex02/'

browser = webdriver.Chrome()
# browser = webdriver.Firefox()
browser.get(url)

# 登錄
username = browser.find_element_by_id('id_username')
username.clear()
username.send_keys('liuhaha')

password = browser.find_element_by_id('id_password')
password.clear()
password.send_keys('123456')
password.submit()

# 重新進入問題頁面
browser.get(url)

for i in range(31):
    username = browser.find_element_by_name('username')
    username.clear()
    username.send_keys('liuhaha')

    password = browser.find_element_by_id('id_password')
    password.clear()
    password.send_keys(i)
    # FireFox下異步身隐,Chrome下同步廷区,submit方法會等待頁面加載完成后返回
    # password.submit()

    # 兩種瀏覽器下click()方法都會等到加載完成后返回
    browser.find_element_by_id('id_submit').click()
    
    returnText = browser.find_element_by_tag_name('h3')
    print(returnText.text + ', password ' + str(i))
    if u"成功" in returnText.text:
        break
    browser.back()

browser.quit()

運行成功頁面:

運行成功頁面
運行成功頁面

總結(jié)

這關(guān)主要考察了登錄過程的模擬,涉及到 cookie 和 post 數(shù)據(jù)的處理抡医。登錄模擬重點在于過程的分析躲因,post 數(shù)據(jù)中各字段意義的分析。僅僅一個猜數(shù)字的網(wǎng)站就這么復(fù)雜忌傻,要是其他更復(fù)雜的網(wǎng)絡(luò)大脉,要順利模擬登錄必須知道每個字段的來源、關(guān)聯(lián)水孩、意義镰矿,那會更加困難!


如果覺得有用俘种,歡迎關(guān)注我的微信秤标,一起學(xué)習(xí)绝淡,共同進步,不定期推出贈書活動~

你的關(guān)注是對我最大的鼓勵苍姜!
你的關(guān)注是對我最大的鼓勵牢酵!
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市衙猪,隨后出現(xiàn)的幾起案子馍乙,更是在濱河造成了極大的恐慌,老刑警劉巖垫释,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丝格,死亡現(xiàn)場離奇詭異,居然都是意外死亡棵譬,警方通過查閱死者的電腦和手機显蝌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來订咸,“玉大人曼尊,你說我怎么就攤上這事∷闾福” “怎么了涩禀?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長然眼。 經(jīng)常有香客問我,道長葵腹,這世上最難降的妖魔是什么高每? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮践宴,結(jié)果婚禮上鲸匿,老公的妹妹穿的比我還像新娘。我一直安慰自己阻肩,他們只是感情好带欢,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著烤惊,像睡著了一般乔煞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上柒室,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天渡贾,我揣著相機與錄音,去河邊找鬼雄右。 笑死空骚,一個胖子當(dāng)著我的面吹牛纺讲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播囤屹,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼熬甚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了肋坚?” 一聲冷哼從身側(cè)響起则涯,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冲簿,沒想到半個月后粟判,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡峦剔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年档礁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吝沫。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡呻澜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惨险,到底是詐尸還是另有隱情羹幸,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布辫愉,位于F島的核電站栅受,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏恭朗。R本人自食惡果不足惜屏镊,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望痰腮。 院中可真熱鬧而芥,春花似錦、人聲如沸膀值。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沧踏。三九已至歌逢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間悦冀,已是汗流浹背趋翻。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人踏烙。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓师骗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讨惩。 傳聞我的和親對象是個殘疾皇子辟癌,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容