美文网首页
黑板客爬虫闯关

黑板客爬虫闯关

作者: Koelre | 来源:发表于2018-06-23 17:02 被阅读35次

    第一关:
    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

    相关文章

      网友评论

          本文标题:黑板客爬虫闯关

          本文链接:https://www.haomeiwen.com/subject/arellftx.html