黑板客爬虫闯关

2018-06-23  本文已影响35人  Koelre

第一关:
url: http://www.heibanke.com/lesson/crawler_ex00/
打开网页是这样的

自己试几次就可以发现规律,此次的数字是下一次请求的数字,手动操作任务量还是挺大的,通关后大概是这样:

源码如下:

import os,sys
import re
import requests
reload(sys)
sys.setdefaultencoding('utf-8')
# 第一关 猜数字
# 此次的数字是下一次请求的数字
# url: http://www.heibanke.com/lesson/crawler_ex00/
def ex01():
    # 匹配数字
    def findNum(url):
        res = requests.get(url).content
        num = re.findall('数字[^\d]*(\d+)[\.<]',res)
        return num
    # 首先获得数字
    url = "http://www.heibanke.com/lesson/crawler_ex00/"
    num = findNum(url)
    # 循环直至出来结果
    while num:
        url2 = url+num[0]
        num = findNum(url2)
        print u'访问网页:%s'%url2
    else:
        print u'第二关网页:%s'%url2

以上就是第一关。



接下来是第二关:
url: http://www.heibanke.com/lesson/crawler_ex01/
页面打开是这样的:

通过页面很直观的知道,密码是30以内,所以我就没把30放在考虑范围内,也就是说是0-29。
后来查看此次关卡传的参数,发现出来用户名和密码之外还多了一个csrfmiddlewaretoken,于是就去页面找了下,猜想是这个value,试了下,果然是

源码如下:

#-*- coding:utf-8 -*-

#author:Koelre

# 黑板课爬虫闯关
# url: http://www.heibanke.com/lesson/crawler_ex00/

import os,sys
import re
import requests
from lxml import etree

reload(sys)
sys.setdefaultencoding('utf-8')

# 获取csrf值
def getcsrf():
    url = 'http://www.heibanke.com/lesson/crawler_ex01/'
    res = requests.get(url,timeout=30).text
    tree = etree.HTML(res)
    csrf = tree.xpath('/html/body/div/div/div[2]/form/input/@value')[0]
    return csrf



# 第二关 猜密码
# 密码是30以内,所以我就没把30放在考虑范围内,就是0-29
# url: http://www.heibanke.com/lesson/crawler_ex01/
def ex02():
    scrf = getcsrf()
    url = 'http://www.heibanke.com/lesson/crawler_ex01/'
    data = {
    "csrfmiddlewaretoken": str(scrf),
    "username": "a",
    "password": "1"
    }
    for x in xrange(30):
        data["password"] = x
        res = requests.post(url,data=data).content
        if u"错误" not in res:
            print u"密码:%s"%x
            break



接下来是第三关:
url: http://www.heibanke.com/lesson/crawler_ex02/
页面打开是这样的:

这个首先就需要登录啦,注册登录之后打开就是这样的:

所以,第三关相对第二关就需要登录了,密码还是30以内,所以我就没把30放在考虑范围内,就是0-29



接下来是第四关:
url: http://www.heibanke.com/lesson/crawler_ex03/
页面打开是这样的:

看见这样蒙圈,于是输入试试:

发现已经不是输入密码那么简单了,所以 在这里耐心找

上下翻了几页也才明白,意思是说:虽然说同样需要登录,我看了好几遍才清楚它的密码逻辑,“密码的位置”最大的是100,所以,密码长度应该是100个,如果只是遍历完一遍显示的页数,数字可能会达不到100个,所以这样就需要循环几遍才能得到所有的。



接下来是第五关:
url: http://www.heibanke.com/lesson/crawler_ex04/
页面打开是这样的:

发现除了需要登录,输入密码(同样是数字 - 就从0开始),还多了一个验证码,经查看,验证码就是一种图片,我的方案就是每次把那个图片下载下来在本地识别就OK了。

源码如下:

#-*- coding:utf-8 -*-

# 黑板课爬虫闯关
# url: http://www.heibanke.com/lesson/crawler_ex00/

import os,sys
import re
import random
import requests
from lxml import etree
import pytesseract
from PIL import Image,ImageEnhance

reload(sys)
sys.setdefaultencoding('utf-8')

# 登录 
# 3,4,5都需要登录
# url: http://www.heibanke.com/accounts/login
def login():
    website1 = 'http://www.heibanke.com/accounts/login'
    se = requests.Session()
    se.get(website1)
    token1 = se.cookies['csrftoken']# 保存csrftoken  
    # 登录参数
    dataWebsite1 = {
        'username': 'Koelre',  
        'password': 'lixue961314',  
        'csrfmiddlewaretoken': token1  
    }
    res = se.post(website1, data=dataWebsite1)#登录
    print res.status_code
    return se


# 第三关 猜密码
# url: http://www.heibanke.com/lesson/crawler_ex02/
def ex03():
    website2 = 'http://www.heibanke.com/lesson/crawler_ex02/'
    s = login()# 登录
    for x in xrange(30):
        # 以下步骤原理和上面一样
        token2 = s.cookies['csrftoken']
        dataWebsite2 = {
        'username': 'a',  
        'password': x,  
        'csrfmiddlewaretoken': token2
        }
        result = s.post(website2, data=dataWebsite2).content
        if u"错误" not in result: 
            print u"3--密码:%s"%x
            break



# 第四关 猜密码
# url: http://www.heibanke.com/lesson/crawler_ex03/
def guesspass(se,password):
    website2 = 'http://www.heibanke.com/lesson/crawler_ex03/'
    dataweb2 = {
    "csrfmiddlewaretoken": "JUwPvezXy54mqH5MrklkBSiecn1ZZnqv",
    "username": "a",
    "password": password
    }
    req = se.post(website2,data=dataweb2).content
    return req

# 收集密码的值
passes = ['' for x in range(101)]
def ex04():
    global passes
    se = login()# 登录
    # for i in range(1,14):
    passwebsite = 'http://www.heibanke.com/lesson/crawler_ex03/pw_list/?page=1'#+str(i)
    # 密码
    res = se.get(passwebsite).content
    etr = etree.HTML(res)
    # 第一个是标题
    trs = etr.xpath('/html/body/div/div/div/table/tr')[1:]
    for tr in trs:
        pa1 = tr.xpath('td[1]/text()')[0].strip()#密码位置
        pa1 = int(re.findall('\d+',pa1)[0])
        pas = tr.xpath('td[2]/text()')[0].strip()#密码的值
        passes[pa1] = pas
    password = ''.join(passes)#把密码拼接字符串
    if len(password)==100:
        # 猜密码
        result = guesspass(se,password)
        # 判断密码是否猜对
        if u"错误" not in result: 
            print u"4--密码:%s"%password
    else:
        ex04()


# 第五关
# url: http://www.heibanke.com/lesson/crawler_ex04/
def VerificationCode(imgurl):
    # 保存验证码
    imgs = requests.get(imgurl).content
    with open('1.jpg','wb') as f:
        f.write(imgs)
        
    image = Image.open('1.jpg')
    imgry = image.convert('L')#图像加强,二值化
    sharpness = ImageEnhance.Contrast(imgry)#对比度增强
    sharp_img = sharpness.enhance(2.0)
    sharp_img.save('1.jpg')

    text = pytesseract.image_to_string(image)
    return text

def ex05(a=1,passd=1):
    website = 'http://www.heibanke.com/lesson/crawler_ex04/'
    se = login()# 登录
    res1 = se.get(website)
    # print res1.status_code
    etr = etree.HTML(res1.content)
    token2 = etr.xpath('/html/body/div/div/div[2]/form/input/@value')[0].strip()
    imgsrc = etr.xpath('/html/body/div/div/div[2]/form/div[3]/img/@src')[0].strip()
    #验证码链接
    imgurl = 'http://www.heibanke.com'+str(imgsrc)
    #图片code
    capcodes = etr.xpath('//*[@id="id_captcha_0"]/@value')[0]
    # 保存验证码图片且识别验证码
    text = VerificationCode(imgurl)
    # print capcodes,text,passd
    web2data = {
        "csrfmiddlewaretoken":token2,
        "username":"a",
        "password":passd,
        "captcha_0":capcodes,
        "captcha_1":text
    }
    # 提交信息 - 开始猜测
    # 尝试每个数字多猜几次,验证码有时候会识别错误
    res2 = se.post(website,data=web2data,timeout=30).content
    if u"验证码输入错误" not in res2:
        if u"密码错误" not in res2:
            with open('pass.txt','ab') as f:
                f.write(u"密码是:%s"%passd)
        else:
            ex05(a,passd+1)
    else:
        # 多输入几次验证码,预防验证码错误
        if a<=3:
            ex05(a+1,passd)
        else:
            a=1
            ex05(a,passd+1)



github上面也放源码了,点它就可以了 -- >> github-crawler

上一篇下一篇

猜你喜欢

热点阅读