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

环境:

vmware上安装windows 32位系统:windows xp / windows 7

selenium版本: 3.11.0

IEDriverServer版本: win32_3.9.0, 放在C:\Program Files\Internet 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);

使用WinIo32绕过密码控件实现自动登录的更多相关文章

  1. asp.net 不用控件,自动登录(用于和其他系统对接的时候,自动登录系统,用户体验好)

    if (System.Web.Security.Membership.ValidateUser("admin", "123456")) { //这句话很重要,他 ...

  2. 基于MVC4+EasyUI的Web开发框架经验总结(13)--DataGrid控件实现自动适应宽带高度

    在默认情况下,EasyUI的DataGrid好像都没有具备自动宽度的适应功能,一般是指定像素宽度的,但是使用的人员计算机的屏幕分辨率可能不一样,因此导致有些地方显示太大或者太小,总是不能达到好的预期效 ...

  3. DevExpress.LookUpEdit控件实现自动搜索定位功能 兼使用方法(looUpEdit可编辑)

    DevExpress.LookUpEdit 使用方法 设置可手动输入 this.LookUpEdit1.Properties.TextEditStyle = DevExpress.XtraEditor ...

  4. H5端密码控件自动化测试

    最近在做H5端UI自动化测试,其中遇到了一个棘手问题就是密码控件,因为密码控件的按钮每次都是随机不一样的,没法固定去点击输入密码.密码的输入框是div不是input,所以没法用send_keys()这 ...

  5. Android——控件AutoCompleteTextView 自动提示

    Android:控件AutoCompleteTextView 自动提示 在输入框中输入我们想要输入的信息就会出现其他与其相关的提示信息,这种效果在Android中是用AutoCompleteTextV ...

  6. (转)基于MVC4+EasyUI的Web开发框架经验总结(13)--DataGrid控件实现自动适应宽带高度

    http://www.cnblogs.com/wuhuacong/p/4085725.html 在默认情况下,EasyUI的DataGrid好像都没有具备自动宽度的适应功能,一般是指定像素宽度的,但是 ...

  7. 详解DevExpress.LookUpEdit控件实现自动搜索定位功能(转)

    转载自csdn博客 爱拼才会赢 的博客 地址是详解DevExpress.LookUpEdit控件实现自动搜索定位功能(转)

  8. PassGuard密码控件配置

    运行环境 win服务器 系统server2008R2 C# ASP.NET服务器页面 前端部分      1.引用 //JS部分引用 <script type="text/javasc ...

  9. Asp.Net2.0下C#环境 Login控件实现用户登录

    原文:Asp.Net2.0下C#环境 Login控件实现用户登录 一.前台显示效果 二.前台代码             <asp:Login ID="Login1" run ...

随机推荐

  1. Linux如何修改和查询时区时间

    Linux如何修改和查询时区时间 我在日常工作中,最近遇到了在解压源码包的时候,提示时间比较旧,解压安装出现问题.原因是,租用的vps所在时区和自己所需要的时区不一致,于是在网上找了相关资料.并亲自实 ...

  2. POJ1821 单调队列//ST表 优化dp

    http://poj.org/problem?id=1821 当我们在考虑内层循环j以及决策k的时候,我们可以把外层变量i看作定值,以此来优化dp状态转移方程. 题意 有n个工人准备铺m个连续的墙,每 ...

  3. 【C#】C#获取文件夹下的所有文件

    #基础知识 1.获得当前运行程序的路径 string rootPath = Directory.GetCurrentDirectory(); 2.获得该文件夹下的文件,返回类型为FileInfo st ...

  4. JavaEE之JDBC编程[详解]

    1.数据库简介 数据库(DB,Data Base ) 数据库管理系统(DBMS,Data Base Management System) 关系型数据库(RDB) 关系型数据库管理系统(RDBMS) S ...

  5. python django基础三 模版渲染

    request对象 当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象.Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 reque ...

  6. Hadoop记录-安装ambari hdp集群

    #!/bin/sh #配置用户sudo权限(参考/etc/sudoers文件,在/etc/sudoers.d/新建一个用户配置文件,注意要注销) #需要在/etc/sudoers末尾追加:sfapp ...

  7. 服务器SSL不安全漏洞修复方案

    关于SSL POODLE漏洞 POODLE = Padding Oracle On Downgraded Legacy Encryption.是最新安全漏洞(CVE-2014-3566)的代号,俗称“ ...

  8. ArcGis辅助编号(半自动)功能的插件式实现

    应邀写了一个ArcGis(ArcMap更确切一些)的辅助编号功能,其实只要想通了实现逻辑,实现的过程蛮简单的.相比挨个儿点要素写进编号或者借助“按键精灵”写入,直接操作宿主真是爽快得不能自已.无图言屌 ...

  9. Postman 安装及使用入门教程 (谷歌浏览器插件版)

    postman 在 谷歌浏览器中插件版 http://www.cnblogs.com/mafly/p/postman.html Postman 4.1.2 下载地址: http://files.cnb ...

  10. 子线程导致 Windows 服务停止的情况(Topshelf 结合 Quartz.NET)

    Ø  前言 本文主要记录子线程导致 Topshelf 和 Quartz.NET 的 Windows 服务停止的现象,以及使用几种常用子线程的注意事项.因为我们有时可能需要开启多个线程执行复杂的逻辑,如 ...