第三關(guān)開始有點難度了帆阳,本關(guān)的難點就是所謂的兩層認(rèn)證
橱夭,需要獲取處理 cookie
氨距。
闖關(guān)地址是:http://www.heibanke.com/lesson/crawler_ex02/
頁面分析
剛進入頁面時沒看懂是怎么玩,以為到這就結(jié)束了棘劣,抱著試試看的態(tài)度注冊了下俏让。

注冊登錄后,發(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,但并無實際作用属愤,可忽略女器;

第 2 步
瀏覽器向 LOGIN_URL 發(fā)出新的 GET 請求。我們注意到請求和響應(yīng)中帶了一個 cookie住诸,其中都有一個 csrftoken
字段驾胆,其值為 708NMR2acyRWlblKw0rBqSjayL70TJDT。
如果仔細(xì)觀察贱呐,第一步請求頭的 cookie 中也有這么一個字段丧诺,我們將其記下,此 csrftoken 都將作為以后訪問過程中的依據(jù)之一奄薇。我們將此返回的 cookie 記為 c1驳阎;

第 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;


登錄成功后废睦,發(fā)現(xiàn)還是第二關(guān)的猜數(shù)字游戲伺绽。只不過,這次猜數(shù)字之前需要先進行登錄嗜湃,獲取 cookie奈应。
第 4 步
頁面填寫昵稱和數(shù)字,點擊提交购披,瀏覽器向 URL 提交 POST 請求杖挣,請求標(biāo)頭附帶的是第 3 步的 cookie c2,請求正文是昵稱密碼和 cookie c2 中的 csrftoken 對應(yīng)的值刚陡。


后面的步驟就和第二關(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í)绝淡,共同進步,不定期推出贈書活動~
