人行征信模拟登陆

有了之前的基础理论,就可以付诸实践啦
典型案例是央行征信报告系统的官网,年初在登陆页面加入了安全控件
并且只可以通过IE浏览器登陆

image.png

其中的密码输入框就是安全性更高的控件输入,由于我的浏览器已经安装过控件了,所以在密码输入未知显示的是控件框,仔细对比登陆名的dom框,还是可以看出区别的

1. 准备

需要一台windwos电脑,带IE浏览器,进入央行征信登陆页面:
https://ipcrs.pbccrc.org.cn/
安装好输入框控件
python环境的话,安装selenium包,配好iedriver,这里的操作网上教程一大堆,略过

2. 登陆分析
image.png

抓包分析,可以找到登陆入口

输入登陆名、输入密码、验证码,点击登陆按钮即可登陆:
这里先异步调用打码平台打码
然后selenium输入登陆名,winIO输入密码,等待打码完成输入验证码最后提交

3. 实践

我们创建一个模拟登陆类,将整套登陆操作封装一起来
初始化部分:

def __init__(self):
   self.driver = webdriver.Ie()
   self.coo = {}
   self.captch = ''
   self.event = Event()

driver变量用表示浏览器实例
coo变量:登陆成功的cookie
captch:验证码

基础设施:

验证码用打码平台的,控件输入密码使用之前准备好的winIO输入
其中打平台的打码时间不太稳定,我们采用线程异步的方式打码
from threading import Thread, Event
简单介绍下Event,这个对象是一个线程安全的事件信号,调用打码平台的时候先调用Event.set()方法,在其他线程同步完成系列操作之后可以调用Event.wait(time)方法,等待time时间,这里给打码平台设置5s等待时间,超时打码未完成则认作打码失败,更多进程线程介绍点这里:http://kaito-kidd.com/2018/05/11/python-advance-process-thread/

    def async_ocr(self):
        t = Thread(target=self.ocr)
        t.setDaemon(True)
        t.start()

    def ocr(self):
        #调用打码方法
        rst = TesFunc2(self.img)
        self.captch = rst
        self.event.set()

winIO的包装:
之前介绍了winIO:https://www.jianshu.com/p/40a9de88153f
把输入密码的api进一步封装到类中:

    def passwd(self, pwd):
        for i in pwd:
          input_key(i)
          time.sleep(0.1)
主体登陆逻辑

1.请求登陆接口:

    def start(self):
        self.driver.get('https://ipcrs.pbccrc.org.cn/page/login/loginreg.jsp')
        img = 'pictures/{}.png'.format(time.time())
        self.driver.save_screenshot(img)
        element = self.driver.find_element_by_xpath('//img[@class="yzm_img"]')
        left = element.location['x']
        top = element.location['y']
        right = element.location['x'] + element.size['width']
        bottom = element.location['y'] + element.size['height']

        im = Image.open(img)
        im = im.crop((left + 23, top + 1, right, bottom))
        im.save(img)
        self.img = img
        # self.hand = self.driver.current_window_handle
        self.captch = ''

该方法的作用是请求登陆页面,截取验证码保存为bytes类型,后面调用打码平台,打码
截屏用的selenium的diver对象的方法,抠图需要用到pillow库,导入:
from PIL import Image
其中的im.crop方法四个参数是验证码的像素点,浏览器可能略有误差,调整了一下左侧向右偏移了20多像素

2.输入登陆信息:

    def form_submit_control(self, username, pwd):
        # 异步打码
        self.async_ocr()
        time.sleep(0.1)
        self.passwd(pwd)
        name = self.driver.find_element_by_xpath('//input[@id="loginname"]')
        name.send_keys(username)
        img = self.driver.find_element_by_xpath('//input[@id="_@IMGRC@_"]')
        # 等待打码时间通知
        try:
            self.event.wait(5)
        except:
            pass
       
        if not self.captch:
            return  '打码平台异常'
        img.send_keys(self.captch)
        submit = self.driver.find_element_by_xpath('//input[@type="submit"]')
        submit.click()
      """"此处处理登陆后续操作..."""

整体的登陆逻辑就完成了

你可能感兴趣的:(人行征信模拟登陆)