1. 程式人生 > >Python:黑板課爬蟲闖關第三關

Python:黑板課爬蟲闖關第三關

註冊 之前 ear crawler htm csrf href else 技術分享

第三關開始才算是進入正題了。

輸入網址 http://www.heibanke.com/lesson/crawler_ex02/,直接跳轉到了 http://www.heibanke.com/accounts/login/?next=/lesson/crawler_ex02/,顯示如下

技術分享圖片

看到這個一楞,怎麽不是第三關呢?不管,也許是標題不一樣吧。點個註冊看了下,裏面有個驗證碼,頓時以為是考驗證碼破解。

註冊以後,跳轉到不知道哪裏去了,重新輸入 http://www.heibanke.com/lesson/crawler_ex02/,一看,原來想錯了。

技術分享圖片

原來這才是第三關,首先可以肯定的是,必須要先登錄,並保持登錄狀態,否則是爬不過關的。

我用的是谷歌瀏覽器,打開開發者工具,隨便輸了個昵稱和密碼,追蹤一下網絡請求

技術分享圖片

這個 csrfmiddlewaretoken 又是個什麽鬼,哪裏來的?

用代碼試下登錄看。post 用戶名密碼之後,print 一下響應的 html,發現並不是我看到的第三關的內容,說明登錄沒有成功。看一下裏面有一句話:You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties.

簡單的說,就是為了防止CSRF攻擊(其實就是黑板課設的障礙),需要一個cookie。那麽就簡單了,csrfmiddlewaretoken 想必就是那個 cookie 了。

追蹤一下登錄的網絡請求,發現也有 csrfmiddlewaretoken,想必內外是一樣的機制。

技術分享圖片

請求網址的時候,返回一個名為 csrftoken 的 cookie,這個 cookie 的值就是 post 的時候需要的 csrfmiddlewaretoken 參數。

這樣思路就理清了,每次 post 用戶名密碼之前,先 get 請求一下,從服務器發給你的 cookie 中獲取 csrftoken 的值作為 post 時的 csrfmiddlewaretoken 參數即可。

代碼如下:

import re
import requests
import time


def main():
    url_login = http://www.heibanke.com/accounts/login/?next=/lesson/crawler_ex02/
    url = http://www.heibanke.com/lesson/crawler_ex02/
    session = requests.Session()
    # 獲取cookie
    session.get(url_login)
    token = session.cookies[csrftoken]
    # 登錄
    session.post(url_login, data={csrfmiddlewaretoken: token, username: guliang21, password: 123qwe})
    for psd in range(30):
        print(ftest password {psd})
        session.get(url)
        token = session.cookies[csrftoken]
        r = session.post(url, data={csrfmiddlewaretoken: token, username: aa, password: psd})
        html = r.text
        if 密碼錯誤 not in html:
            m = re.search((?<=\<h3\>).*?(?=\</h3\>), html)
            print(m.group())
            m = re.search((\<).*?href="([^"]*?)".*?(\>下一關\</a\>), html)
            print(f下一關 http://www.heibanke.com{m.group(2)})
            return
        else:
            time.sleep(1)


if __name__ == __main__:
    main()

Python:黑板課爬蟲闖關第三關