Python 爬虫闯关(第三关)

第三关开始有点难度了,本关的难点就是所谓的两层认证,需要获取处理 cookie

闯关地址是:http://www.heibanke.com/lesson/crawler_ex02/

页面分析

刚进入页面时没看懂是怎么玩,以为到这就结束了,抱着试试看的态度注册了下。

爬虫闯关 第三关
爬虫闯关 第三关

注册登录后,发现是一个记账点之类的,网页还没有跳转到题目网页,还不知道怎么玩。

重新从题目地址进入后,发现可以玩了:

题目页面
题目页面

页面提示 比上一关多了两层保护

解题思路

题目中提到了两层保护,是哪两层呢?

首先,多了账号登陆一层,还有一层是什么呢?重新登陆,打开 firebug 记录一下整个流程:

请求处理流程
请求处理流程

从动图中我们可以看到整个流程分为 4 步,依次点击 4 个步骤,分析记录请求标头、请求正文、响应标头、cookies 等是否有值,值为多少,值的来源与请求顺序之间的关系。

为了下文描述方便,我们约定两个变量:

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

第 1 步

首先访问 URL,浏览器会向 URL 发出 GET 请求,得到一个 302 的重定向的响应,响应标头中包含了一个 Location 字段,告诉浏览器新的访问地址 LOGIN_URL

如果之前用同样的浏览器闯过第一关或第二关,此请求的请求标头仍然会带上 cookie,但并无实际作用,可忽略;

第 1 步
第 1 步

第 2 步

浏览器向 LOGIN_URL 发出新的 GET 请求。我们注意到请求和响应中带了一个 cookie,其中都有一个 csrftoken 字段,其值为 708NMR2acyRWlblKw0rBqSjayL70TJDT。

如果仔细观察,第一步请求头的 cookie 中也有这么一个字段,我们将其记下,此 csrftoken 都将作为以后访问过程中的依据之一。我们将此返回的 cookie 记为 c1;

第 2 步
第 2 步

第 3 步

首先我们这里已经注册过了,直接填写登录信息,浏览器会再向 LOGIN_URL 发出 POST 请求,得到一个向第一步中 URL 的 重定向的 302 响应。

请求标头和请求正文中都附带上第二步中的 cookie c1,另外,我们发现请求正文参数中除了 username 和 password 字段外,还有一个 csrfmiddlewaretoken 字段,该字段的值就是 c1 中 csrftoken 的值。

返回的响应标头中附带了两个新的 cookie,其中一个中同样包含了 csrftoken 字段,值为 nmQXET2BHzNbhCksAur9XtLjEiYnfTC4,后面猜数字就会用到。我们将此返回的 cookies 记为 c2;

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

登录成功后,发现还是第二关的猜数字游戏。只不过,这次猜数字之前需要先进行登录,获取 cookie。

第 4 步

页面填写昵称和数字,点击提交,浏览器向 URL 提交 POST 请求,请求标头附带的是第 3 步的 cookie c2,请求正文是昵称密码和 cookie c2 中的 csrftoken 对应的值。

第 4 步
第 4 步
第 4 步请求正文
第 4 步请求正文

后面的步骤就和第二关差不多了,只不过需要带上 cookie 和 csrftoken。

整个流程涉及两次 cookie 的获取,这就是题目所谓的两层保护

requests 实现

由于第 1 步返回结果中除了 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'}

# 获取默认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'传入参数为:' + str(playload))

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

    # print(u'执行结果:' + str(r.status_code))

    if r.status_code == 200:
        if u"成功" in r.text:
            print(u'闯关成功!密码为:' + str(i))
            break
    else:
        print(u'Failed')
        break

运行:

$ python crawler_ex02.1.py
Welcome
传入参数为:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 0}
传入参数为:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 1}
传入参数为:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 2}
传入参数为:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 3}
传入参数为:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 4}
传入参数为:{'username': 'liuhaha', 'csrfmiddlewaretoken': 'oQxtpIFUtJHIeg03aKGUuieGWSl4UXve', 'password':
 5}
闯关成功!密码为:5

使用 selenium 实现

使用 selenium 实现方式好像不涉及验证之类的问题,因为完全是模拟的人类登录浏览器的过程。

# 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()

运行成功页面:

运行成功页面
运行成功页面

总结

这关主要考察了登录过程的模拟,涉及到 cookie 和 post 数据的处理。登录模拟重点在于过程的分析,post 数据中各字段意义的分析。仅仅一个猜数字的网站就这么复杂,要是其他更复杂的网络,要顺利模拟登录必须知道每个字段的来源、关联、意义,那会更加困难!


如果觉得有用,欢迎关注我的微信,一起学习,共同进步,不定期推出赠书活动~

你的关注是对我最大的鼓励!
你的关注是对我最大的鼓励!
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容