使用WinIo32绕过密码控件实现自动登录
通过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绕过密码控件实现自动登录的更多相关文章
- asp.net 不用控件,自动登录(用于和其他系统对接的时候,自动登录系统,用户体验好)
if (System.Web.Security.Membership.ValidateUser("admin", "123456")) { //这句话很重要,他 ...
- 基于MVC4+EasyUI的Web开发框架经验总结(13)--DataGrid控件实现自动适应宽带高度
在默认情况下,EasyUI的DataGrid好像都没有具备自动宽度的适应功能,一般是指定像素宽度的,但是使用的人员计算机的屏幕分辨率可能不一样,因此导致有些地方显示太大或者太小,总是不能达到好的预期效 ...
- DevExpress.LookUpEdit控件实现自动搜索定位功能 兼使用方法(looUpEdit可编辑)
DevExpress.LookUpEdit 使用方法 设置可手动输入 this.LookUpEdit1.Properties.TextEditStyle = DevExpress.XtraEditor ...
- H5端密码控件自动化测试
最近在做H5端UI自动化测试,其中遇到了一个棘手问题就是密码控件,因为密码控件的按钮每次都是随机不一样的,没法固定去点击输入密码.密码的输入框是div不是input,所以没法用send_keys()这 ...
- Android——控件AutoCompleteTextView 自动提示
Android:控件AutoCompleteTextView 自动提示 在输入框中输入我们想要输入的信息就会出现其他与其相关的提示信息,这种效果在Android中是用AutoCompleteTextV ...
- (转)基于MVC4+EasyUI的Web开发框架经验总结(13)--DataGrid控件实现自动适应宽带高度
http://www.cnblogs.com/wuhuacong/p/4085725.html 在默认情况下,EasyUI的DataGrid好像都没有具备自动宽度的适应功能,一般是指定像素宽度的,但是 ...
- 详解DevExpress.LookUpEdit控件实现自动搜索定位功能(转)
转载自csdn博客 爱拼才会赢 的博客 地址是详解DevExpress.LookUpEdit控件实现自动搜索定位功能(转)
- PassGuard密码控件配置
运行环境 win服务器 系统server2008R2 C# ASP.NET服务器页面 前端部分 1.引用 //JS部分引用 <script type="text/javasc ...
- Asp.Net2.0下C#环境 Login控件实现用户登录
原文:Asp.Net2.0下C#环境 Login控件实现用户登录 一.前台显示效果 二.前台代码 <asp:Login ID="Login1" run ...
随机推荐
- vue(基础二)_组件,过滤器,具名插槽
一.前言 主要包括: 1.组件(全局组件和局部组件) 2.父组件和子组件之间的通信(单层) 3.插槽和具名插槽 ...
- protobuf 编译安装
1.protobuf是google公司提出的数据存储格式,详细介绍可以参考:https://developers.google.com/protocol-buffers 2.下载最新的protobuf ...
- Hadoop记录-hive merge小文件
1. Map输入合并小文件对应参数:set mapred.max.split.size=256000000; #每个Map最大输入大小set mapred.min.split.size.per.no ...
- Web API中给领域模型添加媒体类型支持
一.媒体类型 媒体类型(也称为MIME类型)标识一段数据的格式.在HTTP中,媒体类型描述了消息体的格式.媒体类型由两个字符串组成,一个类型和一个子类型.例如:text / html: image/ ...
- Ado.NET基础必备
一.SqlConnection对象 第一次需要连接数据库时要和服务器握手,解析连接字符串,授权,约束的检查等等操作,而物理连接建立后,这些操作就不会去做了(默认使用了连接池技术). SqlConnec ...
- shop++之language
shop++商城改造此次感悟最深的就是封装.有些东西要整明白就得花点时间. 代码中经常用到这种,我照葫芦画瓢竟然没有用. 天啦,竟然是自己没有定义,还以为是什么高级自动的玩意呢? 文件结构如下: 后面 ...
- 理解self与this
刚开始学习Python的类写法的时候觉得很是麻烦,为什么定义时需要而调用时又不需要,为什么不能内部简化从而减少我们敲击键盘的次数?你看完这篇文章后就会明白所有的疑问. self代表类的实例,而非类. ...
- Javascript的作用域和闭包(一)
一.作用域是什么? 几乎所有的编程语言最基本的功能之一,就是能够存储变量的值,并且能访问和修改这些值. 修改变量值的过程我们通常在程序执行时,称为改变一个对象的状态.有了状态,让程序变得有非常有趣. ...
- 【leetcode-86】 分隔链表
(1过) 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前. 你应当保留两个分区中每个节点的初始相对位置. 示例: 输入: head = 1-> ...
- HDU - 5119 Happy Matt Friends(dp)
题目链接 题意:n个数,你可以从中选一些数,也可以不选,选出来的元素的异或和大于m时,则称满足情况.问满足情况的方案数为多少. 分析:本来以为是用什么特殊的数据结构来操作,没想到是dp,还好队友很强. ...