Python爬虫黑板客闯关

针对黑板客老师给出的爬虫闯关,本文给出了对应每关的思路及代码,目前更新到第四关,持续更新中,欢迎交流指教。有初学爬虫的童鞋有兴趣也可去自己去黑板客进行闯关,闯关地址在下方都有给出,欢迎闯关过后来进行交流。

思路讲解

第一关

第一关入口地址为:http://www.heibanke.com/lesson/crawler_ex00/,打开网页我们可以看到如下页面:

diyiguan

分析:很容易的可以看出,该关就是在网页上给出数字,然后把数字加到网址后面去;在新的网页中将数字不断更新,然后再把数字添加到网址后,循环往复,直到出现新的页面。

代码编写的思路为:通过第一关入口地址获取网页,从网页中提取数字,再将数字加到网址后面得到新的url地址;通过新的url地址获取网页,提取数字,若提取成功则将数字加到入口地址的后面得到新的url,提取失败则可能是第一关结束,输出最后一个获取到的数字或者最后一个网页的内容进行观察;循环上一步;最后得到如下图结果即为通过:

Result

第二关

第二关的入口地址为:http://www.heibanke.com/lesson/crawler_ex01/。打开网页我们可以看到如下页面:

dierguan

分析:通过观察网页可以看出,该关需要向网页提交昵称(任意)+密码(30以内的某个数字);输入正确的密码即可通过本关。

代码编写思路为:输入入口地址;输入账号密码,右键审查,切换到网络;点击提交按钮,观察向网页提交的数据发现包含以下三项(经测试,不想网页提交第一项也可以):

csrfmiddlewaretoken 一串随机值
username 随便输入
password 30以内的数字

账号密码都是我们进行输入的,至于第一项csrfmiddlewaretoken是在入口网页中设置的一串随机验证码。获取到csrfmiddlewaretoken我们可以有两个方法:一是我们可以对入口网页查看源代码,就可以发现网页的源代码中有该标签和它的值;二是可以通过使用requests获取到入口网页返回的cookie值,其中就包含csrfmiddlewaretoken的值。解决了第一项的问题,我们可以通过循环来向网页提交密码进行猜测,直到获取不到“密码错误”字符串,输出最后的网页。

代码(为Python2.x环境,Python3需要简单修改)

第一关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding: utf-8 -*-
import urllib
import re
from bs4 import BeautifulSoup

url="http://www.heibanke.com/lesson/crawler_ex00"
while True:
html=urllib.urlopen(url).read()
#这里使用到了beautifulsoup解析网页,便于后面获取数字
soup=BeautifulSoup(html,"lxml")
str=soup.h3.string
print soup.h3.string
q=re.findall(r"\d+",str)
if q:
p=q[0]
url="http://www.heibanke.com/lesson/crawler_ex00/"+p
else:
print html
break

第二关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!coding:utf-8  
import urllib
import urllib2
import httplib
from bs4 import BeautifulSoup

i=0
while True:
#定义请求头,参考浏览器
headers={
'Host':' www.heibanke.com',
'User-Agent':' Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36',
'Referer':' http://www.heibanke.com/lesson/crawler_ex01/',
'Content-Type':'application/x-www-form-urlencoded'
}
#定义post参数

reqdata={
'username':'jj',
'password':i
}
print reqdata['password']
#对请求数据进行编码
data=urllib.urlencode(reqdata)

#连接请求
conn=httplib.HTTPConnection('www.heibanke.com',80,timeout=30)

#提交请求
conn.request('POST', '/lesson/crawler_ex01/', data, headers)

#获取服务器的返回
res=conn.getresponse()
html=res.read()
soup=BeautifulSoup(html,"lxml")
res=soup.h3.string
print res
if res==u'您输入的密码错误, 请重新输入':
i=i+1
else:
break