• 使用WinIo32绕过密码控件实现自动登录


    通过winIO32绕过密码控件,实现自动登录

    环境:
    vmware上安装windows 32位系统:windows xp / windows 7
    selenium版本: 3.11.0
    IEDriverServer版本: win32_3.9.0, 放在C:Program FilesInternet Explorer目录下
    python版本: 2.7.14

    实现思路:
    1.由于密码控件无法用html元素定位,所以首先计算出密码控件的坐标位置;
    2.模拟鼠标点击获取密码输入框焦点,再使用winIO32实现模拟键盘输入密码;
    3.登录名使用selenium填写    
    4.图片验证码获取到位置后截图,调用打码服务,然后使用selenium填写识别后的验证码;   
    5.通过selenium获取到登录按钮,点击登录,最后返回登录成功的cookie。  
    
    python实现代码:
    使用pip安装以下模块:
    flask
    flask-script
    pillow
    pyautogui
    requests
    selenium
    

    启动服务,地址:127.0.0.1:80

    开发环境启动方式:
    python login_service.py runserver -h 127.0.0.1 -p 80
    
    生产环境启动方式:
    uwsgi --socket 0.0.0.0:80 --protocol=http --wsgi-file myflaskapp.py --callable app --processes 4 --threads 2 --stats 0.0.0.0:9191
    
    # -*- coding: UTF-8 -*-
    # login_service.py 登录请求入口
    from flask import Flask
    from flask.ext.script import Manager
    import selenium_service
    
    app = Flask(__name__)
    manager = Manager(app)
    
    
    @app.route('/login/<username>/<password>')
    def login(username, password):
    	print('request is coming, params:%s, %s' % (username, password))
    	ret = {}
    
    	#这边参数要转字符串格式,否则驱动在模拟键盘输入密码时会有问题
    	ret = selenium_service.login(str(username), str(password))
    	return ret
    
    
    @app.route('/')
    def hello():
    	return 'hello world'
    	
    
    if __name__ == '__main__':
    	manager.run()
    
    # -*- coding: UTF-8 -*-
    # selenium_service.py 调用selenium登录
    import os
    import time
    import json
    from selenium.common.exceptions import UnexpectedAlertPresentException
    import parse_img
    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from PIL import Image
    import pyautogui
    import ctypes_util
    import sys
    
    reload(sys)
    sys.setdefaultencoding('utf-8')
    
    timestamp = str(int(round(time.time() * 1000)))
    iedriver1 = 'C:/Program Files/Internet Explorer/IEDriverServer.exe'
    os.environ['webdriver.ie.driver'] = iedriver1
    img_name = timestamp + '.png'
    new_img_name = 'new_' + img_name
    browser = None	
    
    def home():
        lct = None
        try:
    		global browser
    		browser = webdriver.Ie(iedriver1)
    		browser.get('https://www.xxxx.com/login/loginreg.jsp')
        except UnexpectedAlertPresentException as e:
            print('unexpected alert present when visit the website.')
    
    def refresh():
    	#点击刷新图片验证码
    	browser.find_element_by_class_name('yzm_a').click()
    	
    def switchToCurrentWindow():
    	h = browser.current_window_handle
    	browser.switch_to.window(h)
    	
    def getImg():
    	element = browser.find_element_by_class_name('yzm_img')
    	#switchToCurrentWindow()
    	browser.get_screenshot_as_file(img_name)
    	im = Image.open(img_name)
    	left = element.location['x']
    	top = element.location['y']
    	right = element.location['x'] + element.size['width']
    	bottom = element.location['y'] + element.size['height']
    	region = im.crop((left, top, right, bottom))
    	# 保存图片验证码
    	region.save(new_img_name)
    	# 调用打码服务识别图片验证码
    	code = parse_img.parseImage(new_img_name)
    	removeImg(img_name)
    	removeImg(new_img_name)
    	print('parse img return code:' + code)
    	return code
    
    def input(username, password, code):
    	browser.maximize_window()
    	x1 = 210
    	y1 = 350
    	# 点击获取密码输入框焦点
    	pyautogui.click(x1,y1)
    	# 调用winIo驱动输入密码
    	try:
    		ctypes_util.typestr(password)
    	except Exception as e:
    		print(e)
    	# 输入用户名和图片验证码
    	browser.find_element_by_id('_@IMGRC@_').send_keys(code)
    	browser.find_element_by_id('loginname').send_keys(username)
    	#点击登录按钮
    	browser.find_element_by_class_name('btn2').click()
    	
    
    def login(username, password):
    	try:
    		home()
    		code = getImg()
    		if len(code.strip()) != 6 or code == 'ERROR':
    			refresh()
    			code = getImg()
    		input(username, password, code)
    		browser.implicitly_wait(0.5)
    	except Exception as e:
    		print(e)
    	#登录结果检查
    	#status: -1表示验证码错误,0表示登录名或密码错误,1表示登录成功,-2表示未知错误
    	status = 0
    	result = ''
    	errMsg = ''
    	_msg_ = ''
    	lgnInfo = ''
    	pwdInfo = ''
    	
    	try:
    		lgnInfo = browser.find_element_by_id('loginNameInfo').text
    		pwdInfo = browser.find_element_by_id('passwordInfo').text
    		print('loginNameInfo:%s, passwordInfo:%s' %(lgnInfo, pwdInfo))
    	except:
    		print('loginNameInfo or passwordInfo not exist!')
    		
    	try:
    		errMsg = browser.find_element_by_id('_error_field_').text
    	except:
    		print('errMsg not exist!')
    	
    	try:
    		_msg_ = browser.find_element_by_id('_@MSG@_').text
    	except:
    		print('_msg_ not exist!')
    		
    	print('errorMsg:' + errMsg)
    	print('_msg_:' + _msg_)
    	
    	msg = errMsg if errMsg != '' else _msg_	
    	inputInfo = lgnInfo if lgnInfo != '' else pwdInfo
    	print('msg=' + msg)
    	if len(msg.strip()) > 0:
    		if '验证码输入错误' in msg:
    			status = -1
    		elif '登录名或密码错误' in msg:
    			status = 0
    		else:
    		    status = -2
    	elif len(inputInfo.strip()) > 0:
    		status = -3
    		msg = '登录名或密码输入错误,请重试!'
    	else:
    		status = 1
    		msg = '登录成功'
    		result = ';'.join([item['name'] + '=' + item['value'] for item in browser.get_cookies()])
    	#关闭browser
    	browser.quit()
    	#组装返回报文
    	ret = {}
    	ret['result'] = result
    	ret['status'] = status
    	ret['message'] = msg
    	return json.dumps(ret, ensure_ascii=False)
    		
    def removeImg(path):
        if os.path.exists(path):
            os.remove(path)
    
    
    if __name__ == '__main__':
    	result = login('sel2364', 'sel2364')
    	print(result)
    
    # -*- coding: UTF-8 -*-
    # ctypes_util.py 调用dll中的函数,模拟键盘输入
    from ctypes import *
    import platform
    
    def typestr(s):
    	if platform.system() == 'Windows':
    		libc = cdll.LoadLibrary('testdll_driver.dll')
    		libc.output(s)
    		
    
    if __name__ == '__main__':
        typestr('aaabbb')
    
    # -*- coding: UTF-8 -*-
    # parse_img.py 调用打码服务
    import requests
    import json
    
    url = "http://xxx.xxxx.com/captcha/parse"
    # fo = open("code.jpg", "rb")
    
    headers={
        "appkey":"******",
        "source":"******"
    }
    
    def parseImage(file):
        fo = open(file, "rb")
        body = fo.read()
        resp = requests.post(url, body, headers=headers)
        #print(resp.content)
        jsonobj = json.loads(resp.content)
        return jsonobj['code']
    
    if __name__ == '__main__':
        code = parseImage("code.jpg")
        print("code=" + code);
    
  • 相关阅读:
    python 正则
    python qrcode二维码生成与识别
    python 轮询,长轮询
    Python随心记--module模块和包
    PHP-AOP简介
    PHP三层结构(下)——PHP实现AOP
    PHP三层结构(上)——简单三层结构
    PHP--翻牌活动(概率中奖..............)
    MySQL(表锁)、PHP(文件锁)锁机制及应用场景
    TP5一对一、一对多关联模型的使用
  • 原文地址:https://www.cnblogs.com/CoolJayson/p/8880116.html
Copyright © 2020-2023  润新知