1 Star 0 Fork 1

wxy_xiaobai/autotesttool

forked from newma/autotesttool 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
tenhe.py 17.43 KB
一键复制 编辑 原始数据 按行查看 历史
wxy_xiaobai 提交于 2019-09-29 12:28 . 完善插件
# -*- encoding:utf-8 -*-
from scrap import BrowserType, BrowserHacker, ImageRecognizer, WxCaptcha
from scrap.net import download
from scrap import Log
from time import sleep
import uuid
# wxy加入
from bs4 import BeautifulSoup
import cv2 as cv
from scrap import easing, server
from selenium.webdriver.common.action_chains import ActionChains
import csv
import time
from selenium.webdriver.common.keys import Keys
import os
USER = u"zhangjinlin223" # u"wuchujie1987" # 测试用户名
PASSWORD = u"hello123" # u"wcj08206915" # 测试密码
PHONE = u"13760010630"
# http://thzwb.thnet.gov.cn/thyy/ui/zwyy/GZTHRCDT/step1
# http://thzwb.thnet.gov.cn/thyy/ui/zwyy/GZTHRCG/step1
step1_url = u"http://thzwb.thnet.gov.cn/thyy/ui/zwyy/GZTHRCDT/step1"
loginUrl = u"http://tyrz.gd.gov.cn/tif/sso/static"
# 技术技能人才引进(人才港)
# 技术技能人才引进
# 海外人才引进绿色通道
type_name = u"技术技能人才引进"
class OrderRobot:
def __init__(self, row=None, writer=None):
self.base = "http://tyrz.gdbs.gov.cn" # 测试网站
self.tmpCode = "temp/code_tmp.png" # 临时验证码图片存放路径
self.tmpBkg = "temp/captcha-bg.png"
self.tmpBlock = "temp/captcha.png"
self.browser = BrowserHacker(BrowserType.CHROME)
self.ir = ImageRecognizer()
self.row = row
self.writer = writer
def __getCodeImageUrl(self):
return self.base + "/am/imageServlet?id=" + str(uuid.uuid4())
def analyCodeImage(self):
self.browser.elementScreenshotByXPath("//div[@class='captcha-body captcha']", self.tmpCode)
code = self.ir.recognize(self.tmpCode)
if not self.__validateCode(code):
Log.i("Code not recognize correct, retry after 1 second")
# self.browser.clickByXPath("//div[@class='captcha-body captcha']")
# codeImg = self.browser.getElementByXPath("//div[@class='captcha-body captcha']")
# self.browser.driver.execute_script('arguments[0].click()', codeImg)
# 延时
# sleep(1)
self.open_login()
return self.analyCodeImage()
else:
return code
def open_login(self):
self.browser.open(loginUrl, 0)
def __login(self, username, password):
# 检测验证码
txt = self.analyCodeImage()
Log.i("Recognize code " + txt)
self.browser.inputTextByXPath("//input[@placeholder='请输入账号']", username)
self.browser.inputTextByXPath("//input[@placeholder='请输入密码']", password)
self.browser.inputTextByXPath("//input[@placeholder='请输入验证码']", txt)
login = self.browser.getElementByXPath("//button[@class='gd-btn gd-btn-primary']")
self.browser.driver.execute_script('arguments[0].click()', login)
def login(self, username, password):
self.open_login()
Log.i("login, 等待class为gd-tabs的元素")
if not self.browser.waitUtilElementPresentByClassName("gd-tabs"):
Log.e("step0, 没有class为gd-tabs的元素,return false")
return False
# li = self.browser.getElementByXPath("//li[@class='gd-tabs-nav gd-tabs-nav-small']")
# self.browser.driver.execute_script('arguments[0].click()', li)
if not self.browser.waitUtilElementPresentByXPath("//div[@class='captcha-body captcha']"):
return False
self.__login(username, password)
sleep(2)
if self.browser.driver.current_url == loginUrl and self.browser.checkElementExistByXPath("//div[@class='gd-alert visible']"):
return False
Log.i("登录成功!!")
return True
# 大厅选择
def step0(self):
Log.i("step0, 等待class为gd-content-ul的元素")
if not self.browser.waitUtilElementPresentByClassName("gd-content-ul"):
Log.e("step0, 没有class为gd-content-ul的元素,return false")
return False
workplace = self.browser.getElementByClassName("gd-content-ul")
items = workplace.find_elements_by_tag_name("li")
if len(items):
for item in items:
Log.i(item.text)
workplace.find_elements_by_tag_name("li")[1].click()
Log.i("在step0中点击了广州市天河区人才服务管理办公室")
return True
else:
Log.i("step0, 获取不到列表")
return False
# 部门选择
def step1(self):
Log.i("step1, 等待class为gd-check-tab-label的元素")
if not self.browser.waitUtilElementPresentByClassName("gd-check-tab-label"):
Log.e("step1, 没有class为gd-check-tab-label的元素,return false")
return False
Log.i("step1, 等待xpath为//button[@class='gd-margin gd-btn gd-btn-primary']的元素")
if not self.browser.waitUtilElementPresentByXPath("//button[@class='gd-margin gd-btn gd-btn-primary']"):
Log.e("step1, 没有xpath为//button[@class='gd-margin gd-btn gd-btn-primary']的元素,return false")
return False
department = self.browser.getElementByClassName("gd-check-tab-label")
department.click() # 选择部门
Log.i("step1中选择了部门")
btnNext = self.browser.getElementByXPath("//button[@class='gd-margin gd-btn gd-btn-primary']")
if btnNext.get_attribute('disabled') == "disabled":
Log.e("Not seleted department, retry to select")
return False
btnNext.click() # 点下一步
Log.i("step1中点击了下一步")
return True
# 业务选择
def step2(self):
Log.i("step2, 等待class为gd-ywList的元素")
if not self.browser.waitUtilElementPresentByClassName("gd-ywList"):
Log.e("step2, 没有class为gd-ywList的元素,return false")
return False
Log.i("step2, 等待xpath为//div[@class='gd-ywList']/ul的元素")
if not self.browser.waitUtilElementPresentByXPath("//div[@class='gd-ywList']/ul"):
Log.e("step2, 没有xpath为//div[@class='gd-ywList']/ul的元素,return false")
return False
busList = self.browser.getElementByXPath("//div[@class='gd-ywList']/ul")
# click firt button
businesses = busList.find_elements_by_tag_name("li")
if len(businesses):
for item in businesses:
content = item.find_elements_by_tag_name("span")[0]
# if content.text == u"本科(含中级职称)人才引进":
if content.text == type_name:
item.find_elements_by_tag_name("button")[0].click()
Log.i("step2, 点击了技术技能人才引进")
return True
else:
Log.e("step2,获取的li列表为空")
return False
# 预约时间
def step3(self):
Log.i("step3, 等待class为gd-content-item的元素")
if not self.browser.waitUtilElementPresentByClassName("gd-content-item"):
Log.e("step3, 没有class为gd-content-item的元素,return false")
return False
Log.i("step3, 等待xpath为//div[@class='gd-tabs-pane']/button[@class='gd-btn gd-btn-primary']/span的元素")
if not self.browser.waitUtilElementPresentByXPath("//div[@class='gd-tabs-pane']/button[@class='gd-btn gd-btn-primary']/span"):
Log.e("step3, 没有xpath为//div[@class='gd-tabs-pane']/button[@class='gd-btn gd-btn-primary']/span的元素,return false")
return False
content = self.browser.getElementByClassName("gd-content")
items = content.find_elements_by_class_name("gd-item-available")
if len(items):
items[-1].find_element_by_xpath('..').find_element_by_xpath('..').find_element_by_xpath('..').click()
Log.i("step3, 找到可以预约的名额,预约日期:" + items[-1].find_element_by_xpath('..').find_element_by_xpath('..').find_element_by_xpath('..').find_elements_by_tag_name("div")[0].find_elements_by_tag_name("span")[0].text + ' ' + items[-1].find_element_by_xpath('..').find_elements_by_tag_name("span")[0].text)
items[-1].click()
return True
else:
Log.e("step3,预约爆满了,找不到预约名额,return false")
return False
# 预约中
def step4(self, phone):
# 获取选择的业务和预约的时间
Log.i(
"step4, 等待xpath为//div[@class='gd-bms']/div/p[@class='gd-nt']/span的元素")
if not self.browser.waitUtilElementPresentByXPath("//div[@class='gd-bms']/div/p[@class='gd-nt']/span"):
Log.e("step4, 没有xpath为//div[@class='gd-bms']/div/p[@class='gd-nt']/span的元素,return false")
return False
Log.i("step4, 等待xpath为//div[@class='gd-bms']/div/p[1]/span的元素")
if not self.browser.waitUtilElementPresentByXPath("//div[@class='gd-bms']/div/p[1]/span"):
Log.e("step4, 没有xpath为//div[@class='gd-bms']/div/p[1]/span的元素,return false")
return False
business = self.browser.getElementByXPath("//div[@class='gd-bms']/div/p[1]/span")
datetime = self.browser.getElementByXPath("//div[@class='gd-bms']/div/p[@class='gd-nt']/span")
self.row[3] = business.text
self.row[4] = datetime.text
self.row[5] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
Log.i("step4, 等待class为gd-input-font的元素")
if not self.browser.waitUtilElementPresentByClassName("gd-input-font"):
Log.e("step4, 没有class为gd-input-font的元素,return false")
return False
# 输入手机号码
txtPhone = self.browser.getElementByXPath("//div[@class='gd-input gd-input-small gd-input-text']/input[@placeholder='请输入手机号']")
txtPhone.send_keys(phone)
# 获取验证码
btnCode = self.browser.getElementByXPath("//tr[@class='gd-input-code']/td/button[@class='gd-hcode gd-btn']")
btnCode.click()
Log.i("step4, 等待xpath为//*[@id='tcaptcha_popup']的元素")
if not self.browser.waitUtilElementPresentByXPath("//*[@id='tcaptcha_popup']"):
Log.e("Not found tcaptcha popup")
return False
# 转换到滑块拼图浮窗
elem = self.browser.getElementByXPath("//iframe[@id='tcaptcha_popup']")
self.browser.switchToFrame(element=elem)
Log.i("step4, 转换到了拼图浮窗")
# 等待滑块
Log.i("step4, 等待滑块")
if not self.browser.waitUtilElementPresent("tcaptcha_drag_thumb"):
Log.e("Not found tcaptcha_drag_thumb")
return False
sleep(1)
self.slide = self.browser.getElementById("tcaptcha_drag_thumb")
return True
def step5(self, slide):
flag = False
for i in range(10):
if not self.validate(slide):
Log.i('step5,第' + str(i+1) + '次' + '验证不通过')
else:
flag = True
Log.i('step5,滑块验证通过,发送短信成功,return true')
break
if flag:
self.browser.switchToFrame()
Log.i("step5, 转换到了默认内容")
for i in range(60):
# 获取客户端发送的验证码
code = server.getCode()
if code.strip() != '':
Log.i('step5, 收到验证码code = ' + code)
txtCode = self.browser.getElementByXPath(
"//div[@class='gd-input gd-input-small gd-input-text']/input[@placeholder='请输入短信验证码']")
txtCode.send_keys(code)
server.setCode("")
Log.i("step5, 输入短信验证码..")
break
Log.i("step5, 等待短信验证码..")
sleep(1)
# 点击提交
btnCommit = self.browser.getElementByXPath(
"//div[@class='gd-tabs-pane']/button[@class='gd-btn gd-btn-primary']/span")
btnCommit.click()
Log.i("step5, 点击了提交按钮..")
sleep(3)
if not self.browser.checkElementExistByXPath("//div[@class='gd-tabs-pane']/button[@class='gd-btn gd-btn-primary']/span"):
Log.i("step5, 预约成功")
self.writer.writerow(self.row)
return True
else:
Log.i("step5, 某种原因导致点击了提交却没有预约成功,可能是预约数满了,可能是账号已经预约")
return False
Log.i("step5, 滑块不通过,预约失败")
return False
def validate(self, slide):
"""
完成滑块的验证并发送短信
"""
# 等待缺口背景图
Log.i("step5验证, 等待缺口背景图")
if not self.browser.waitUtilElementPresent("slideBkg"):
Log.e("Not found slideBkg")
return False
soup = BeautifulSoup(self.browser.driver.page_source, "html.parser")
pret = soup.prettify() # 格式美化
# 获取浮窗中的body元素
body = soup.html.body
# 查找body下所有img元素
Log.i("step5验证, 查找缺口背景图")
srcList = body.find_all('img')
if len(srcList):
# 下载带有缺口图片
Log.i("step5验证, 下载缺口背景图")
if not download(srcList[0].get('src'), self.tmpBkg):
Log.i("step5验证, 下载失败")
return False
img0 = cv.imread(self.tmpBkg)
# 查找到缺口的X轴坐标
point = easing.get_pos(img0)
print(point)
# 下载的图片是原图的两倍,以下计算是按2倍来计算,滑块的初始X轴为24px,滑块图片内的左边空白区的长度为23px
diff = (point - 47) // 2
print(diff)
cv.waitKey(0)
cv.destroyAllWindows()
if point == 0:
Log.i("step5验证, 没有查找到缺口位置,return false")
self.browser.clickById("reload")
return False
Log.i("step5验证, 开始滑动滑块")
self.fake_drag(self.browser.driver, slide, diff)
sleep(2)
Log.i("step5验证, 滑动完后检查是否存在id为tcaptcha_window的元素")
if not self.browser.checkElementExistById("tcaptcha_window"):
Log.i("Captcha verified sueccess!")
return True
else:
return False
def fake_drag(self, browser, knob, offset):
"""
算出滑动轨迹并拖动滑块
"""
# 算出滑块滑动轨迹
offsets, tracks = easing.get_tracks(offset, 1, 'ease_out_quart')
print(offsets)
ActionChains(browser).click_and_hold(knob).perform()
print(tracks)
for x in tracks:
ActionChains(browser).move_by_offset(x, 0).perform()
ActionChains(browser).release().perform()
def do_step1(self):
while not self.step1():
Log.i("第一步操作失败,刷新重试")
self.browser.refresh()
def do_step2(self):
while not self.step2():
Log.i("第二步预约失败,返回第一步操作")
self.browser.driver.execute_script("window.onbeforeunload = function() {};")
self.browser.open(step1_url)
self.do_step1()
def do_step3(self):
while not self.step3():
Log.i("第三步预约失败,返回第一步操作")
self.browser.driver.execute_script("window.onbeforeunload = function() {};")
self.browser.open(step1_url)
self.do_step1()
self.do_step2()
def do_step4(self, phone):
while not self.step4(phone):
Log.i("第四步预约失败,刷新重试")
self.browser.switchToFrame()
self.browser.driver.execute_script("window.onbeforeunload = function() {};")
self.browser.open(step1_url)
self.do_step1()
self.do_step2()
self.do_step3()
# 预约
def book(self, phone):
self.browser.switchToFrame()
self.browser.driver.execute_script("window.onbeforeunload = function() {};")
self.browser.open(step1_url)
self.do_step1()
self.do_step2()
self.do_step3()
self.do_step4(phone)
if self.step5(self.slide):
return True
else:
return False
def close(self):
self.browser.close()
def refresh(self):
self.browser.refresh()
def __validateCode(self, code):
if len(code) > 4:
return False
return code.isalnum()
def main():
server.start()
with open('./config/users.csv', "r", encoding="utf-8") as f:
f_csv = csv.reader(f)
with open('./config/complete' + time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime()) + '.csv', 'w', encoding='utf-8-sig', newline='') as csvfile:
writer = csv.writer(csvfile)
for row in f_csv:
if row[4].strip() == '':
robot = OrderRobot(row, writer)
# try:
# 用户登录
while not robot.login(row[0], row[1]):
pass
# 预约
if not robot.book(row[2]):
if not robot.book(row[2]):
pass
robot.close()
else:
writer.writerow(row)
continue
if __name__ == '__main__':
main()
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wxy_xiaobai/autotesttool.git
git@gitee.com:wxy_xiaobai/autotesttool.git
wxy_xiaobai
autotesttool
autotesttool
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385