使用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 ...
随机推荐
- linux driver ------ platform模型,驱动开发分析
一.platform总线.设备与驱动 在Linux 2.6 的设备驱动模型中,关心总线.设备和驱动3个实体,总线将设备和驱动绑定.在系统每注册一个设备的时候,会寻找与之匹配的驱动:相反的,在系统每注册 ...
- threading:线程创建、启动、睡眠、退出
1.方法一:将要执行的函数作为参数传递给threading.Thread() import threading import time def func(n): global count time.s ...
- 安装 java环境 和 tomcat
安装 java环境 和 tomcat -- JAVA部分 tar xf jdk-8u60-linux-x64.tar.gz cd /root/soft/jdk1.8.0_60 mkdir /usr/l ...
- Spring Boot学习记录03_一些属性配置文件
转自:http://blog.didispace.com/springbootproperties/ 多环境配置(这个地方跟maven的profile配置有点类似) 我们在开发Spring Boot应 ...
- python操作execl学习笔记(一)
本节只记录关于execl的读操作: execl 内容及格式 python3 #!/usr/bin/env python #-*- coding:utf-8 -*- import xlrd import ...
- OS + linux proxy
s Linux主机通过代理服务器进行网络连接 http://www.linuxidc.com/Linux/2015-01/111703.htm 新手用Linux做代理服务器 三招搞定 http://b ...
- UEFI BIOS Rootkit Analysis
catalog . BIOS简介 . UEFI BIOS . EFI编程简介 . UEFI Rootkit 1. BIOS简介 BIOS("Basic Input Output System ...
- 1.单件模式(Singleton Pattern)
创建型模式---单件模式(Singleton Pattern)动机(Motivation): 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性. ...
- Ruby on Rails,一对多关联(One-to-Many)
在上一篇文章中,我们知道通过has_one和belongs_to方法定义一对一关联关系.接下来是更常见的情况,一对多关联.比如老师与所教课程的关系,一个老师负责多个课程.换成对象之间的关系就是:一个老 ...
- SpringCloud微服务之跨服务调用后端接口
SpringCloud微服务系列博客: SpringCloud微服务之快速搭建EurekaServer:https://blog.csdn.net/egg1996911/article/details ...