参考链接https://www.bbsmax.com/A/o75NvDYX5W/

用到的tesserocr模块,安装过程可以参考我之前发的随笔或者网上自行搜索,识别率很低只能多试几次,我也没去研究如何提高识别率,用到再说了。

import re,requests,time,os
from lxml import html
etree=html.etree
import threading
import tesserocr

'''
第五关解析
手工访问走一遍流程;
访问第五关地址,直接跳转到了登录页面,理所应当的想到也是需要先登录;输入账户密码登录,登录之后便看到了第五关内容;
提示是加了验证码,看来这关主要的难点就是要解决识别验证码;直接点击提交看一下post提交了什么内容:
csrfmiddlewaretoken: UHlWykhYxsvErH1m832bMeSwO5gDO0TH
username: 
password: 
captcha_0: b20bddb628387cf5ce3ba3e969c3571be1a70ade
captcha_1: 
我们看到了除了用户名密码和csrftoken外还多了两个参数captcha_0,captcha_1
查看页面元素发现验证码的图片下面有一个隐藏的input框,name就是captcha_0,而再下面的待输入验证码input框的name=captcha_1,可以猜测每个验证码都对应了一个str,提交的时候需要一起带着以便服务端校验。
'''
def main():
    # 访问第三关自动跳转到了这个url,所以首先需要登录
    url_login = 'http://www.heibanke.com/accounts/login/?next=/lesson/crawler_ex04/'
    # 登录成功后,访问第三关url
    url = 'http://www.heibanke.com/lesson/crawler_ex04/'
    # 因为需要通过带着cookie去访问,以便做到会话保持,所以这里用requests.session来做
    session = requests.Session()
    # 获取cookie
    session.get(url_login)
    # 获取csrftoken
    token = session.cookies['csrftoken']
    # 将用户名密码和csrftoken一起提交,并获取返回页面; 登录成功后,携带了token再来访问页面会看到第三关内容,和第二关一样,只不过每次提交时同样需要带着csrftoken,否则还是会报错
    session.post(url_login,
                             data={'csrfmiddlewaretoken': token, 'username': 'tianlegg', 'password': '123456'})
    pwd=0
    while pwd<30:
        page_text = session.get(url).text
        # 这里需要重新获取token
        token = session.cookies['csrftoken']
        # 通过xpath获取图片验证码的路径,拼接图片url
        tree = etree.HTML(page_text)
        img_path = tree.xpath('//img[@class="captcha"]/@src')[0]
        img_url = 'http://www.heibanke.com' + img_path
        # 识别图片验证码,获取识别结果
        result=get_img_code(img_url)
        # 如果没有获取到,重新获取
        if not result:
            continue
        # 获取到的验证码信息
        captcha_0=result[0]
        captcha_1=result[1]
        # 通过浏览器f12查看到提交时所需要的信息
        data={
            'csrfmiddlewaretoken':token,
            'username':'Tianle',
            'password':pwd,
            'captcha_0':captcha_0,
            'captcha_1':captcha_1
        }
        # 在登录的状态下提交信息
        respone_page_text=session.post(url=url,data=data).text
        # 解析页面,进行判断
        tree=etree.HTML(respone_page_text)
        h3_text=tree.xpath('//h3/text()')
        print(f'密码:{pwd} ,提示:{h3_text[0]}')
        if '验证码输入错误' in h3_text:
            continue
        elif '您输入的密码错误, 请重新输入' in h3_text:
            pwd += 1
        else:
            print(h3_text)
            break



def get_img_code(url):
    '''
    下载并解析图片验证码中的信息,返回结果
    :param session:
    :return: captcha_0,captcha_1
    '''
    # 验证码图片的路径就是captcha_0
    captcha_0=url.split('/')[-2]
    # 拼接验证码图片路径
    img_path=captcha_0+'.jpg'
    # 写入本地
    with open(img_path,'wb') as f:
        f.write(requests.get(url=url).content)
    # 解析验证码
    captcha_1=tesserocr.file_to_text(img_path)
    # 删除验证码图片
    os.remove(img_path)
    if len(re.findall('[a-zA-Z0-9]',captcha_1)) == 4:
        return captcha_0,captcha_1

if __name__ == '__main__':
    main()