Selenium 自动化测试之纪念币预约

这篇具有很好参考价值的文章主要介绍了Selenium 自动化测试之纪念币预约。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

摘要

前段时间,2023 贺岁纪念币的预约火热地进行着,当晚我也凭借惊人的手速抢到了 3 *20 = 60 个,某天偶然打开农行预约纪念币网的站,发现预约端口还未关闭,便想着用 Selenium 自动化测试来实现全自动预约纪念币。
经过测试,预约 10 人的时间在 45 - 55 s 左右,速度还可以,但有些地方还可以再优化,如加载 csv 文件获取个人信息、使用多台手机同时接受短信验证码等,上述功能可能会在以后的更新中添加。

声明:本文只用于技术分享,禁止使用本文代码参与各种不当获利行为

Part I:基本 Selenium 自动化

打开农行纪念币预约网址,进入纪念币预约,可见布局如下:

Selenium 自动化测试之纪念币预约,selenium,自动化,python,mysql,android

接下来就是基本的 Selenium 自动化了,F12打开开发者工具,查看 “ 预约 ” 的 Xpath,但通过两次纪念币预约,我发现该元素的 Xpath 是随纪念币更改的,故每次要提前进入该网址获取本次预约的 Xpath。

将所有配置文件放在general_settings.py方便管理

# general_settings.py

# 驱动路径
path_chrome = Service_Chrome("../driver/chromedriver.exe")

# 预约链接
booking_url = "https://eapply.abchina.com/coin/Coin/CoinIssuesDistribution?typeid=202301"

# 预约界面 Xpath
welcome_page_xpath = '/html/body/div[5]/div[2]/table/tbody/tr[5]/td[4]/input[1]'
# main.py

browser = webdriver.Chrome(service=general_settings.path_chrome)  # 使用 Chrome 驱动
browser.get(general_settings.booking_url)


def welcome_page():
    """
    欢迎页面
    :return: None
    """
    browser.find_element(By.XPATH, general_settings.welcome_page_xpath).click()
    browser.find_element(By.XPATH, '//*[@id="I128"]/button[1]').click()  # 同意并继续

接下来,进入今天我们的主战场,布局如下:

Selenium 自动化测试之纪念币预约,selenium,自动化,python,mysql,android

我将此页面分为如下五个部分:

  1. 基本个人信息(姓名、证件号码、手机号码)
  2. 图形验证码
  3. 短信验证码
  4. 兑换网点
  5. 兑换时间

其中,1、4、5 在本 Part 展示,2、3 将在下文展示。

1. 基本个人信息

由于本次自动化是多线程同时进行,且为了个人信息安全和后期再有纪念币预约可以直接使用,故将个人信息放入 MySQL 数据库中,使用 Python 第三方库 pymysql 获取数据库信息并填写。

# general_settings.py

# 数据库信息
host = ""  # 主机名(IP)
port = 3306  # 数据库端口,默认为 3306
user = ""  # 数据库用户名
password = ""  # 数据库密码
database = ""  # 信息所在 database(数据库)
table = ""  # 信息所在 table(表)
# main.py

def info_get(host: str, port: int, user: str, password: str, database: str, table: str):
    """
    通过 MySQL 数据库获取信息
    :param host: 主机名(IP)
    :param port: 数据库端口
    :param user: 数据库用户名
    :param password: 数据库密码
    :param database: 信息所在 database
    :param table: 信息所在 table
    :return: 信息的元组
    """
    info_MySQL = Connection(
        host=host,
        port=port,
        user=user,
        password=password
    )  # 连接数据库
    cursor = info_MySQL.cursor() 
    info_MySQL.select_db(database)  
    cursor.execute(f'SELECT *  FROM {table};')
    result = cursor.fetchall()  # 获取所有信息
    info_mysql = result[thread_index]  # 获取对应进程的个人信息
    cursor.close()
    info_MySQL.close()
    return info_mysql
# main.py

def fill_info(info: tuple):
    """
    填写信息函数
    :param info: 信息元组
    :return: None
    """
    browser.find_element(By.XPATH, '//*[@id="name"]').send_keys(info[1])  # 姓名
    browser.find_element(By.XPATH, '//*[@id="identNo"]').send_keys(info[2])  # 身份证号
    browser.find_element(By.XPATH, '//*[@id="mobile"]').send_keys(info[3])  # 电话号码

2. 兑换网点

兑换网点是一个下拉框对象,可以使用 Selenium 中 Select 函数对网点进行选择。省行、分行、支行都很顺利,但营业处选项遇到了一些问题,营业处的文本为 “营业处 + 当前剩余纪念币数”,若使用select_by_index会导致不知道默认选择的营业处是否还有纪念币。

Selenium 自动化测试之纪念币预约,selenium,自动化,python,mysql,android

故做以下修改:先选择默认营业处,若默认营业处剩余纪念币数 <= 20,则对营业处的列表进行遍历,选择剩余纪念币数 >= 20 的营业处,若都没有剩余,则输出 “ 该营业处没有剩余纪念币 ”。当然,你也可以再对支行、分行甚至省行(只要你能跑)的列表进行遍历,选择有剩余的营业处。

# general_settings.py

# 预约地址
place_arr = ["", "", "", 4]  # 分别为 [省行, 分行, 支行, 默认营业厅序号(从 1 开始为第一个)]
# main.py

def choose_place(province: str, city: str, country: str, default_bank_index: int):
    """
    选择兑换网点
    :param province: 省行名称
    :param city: 分行名称
    :param country: 支行名称
    :param default_bank_index: 默认营业处序号(从 1 开始为第一个营业处)
    :return: None
    """
    select_province = browser.find_element(By.XPATH, '//*[@id="orglevel1"]')  # 选择省行
    Select(select_province).select_by_visible_text(province)
  
	select_city = browser.find_element(By.XPATH, '//*[@id="orglevel2"]')  # 选择分行
    Select(select_city).select_by_visible_text(city)

    select_country = browser.find_element(By.XPATH, '//*[@id="orglevel3"]')  # 选择支行
    Select(select_country).select_by_visible_text(country)

    select_bank = browser.find_element(By.XPATH, '//*[@id="orglevel4"]')  # 选择营业处
    bank_text = select_bank.text
    bank_arr = bank_text.split("\n")
    default_coin_number = bank_arr[default_bank_index].split(" ")

    # 判断该营业处是否有剩余纪念币
    if int(default_coin_number[1]) >= 20:
        Select(select_bank).select_by_index(default_bank_index)
    else:
        for bank_index in range(1, len(bank_arr)):
            coin_number = bank_arr[bank_index].split(" ")
            if int(coin_number[1]) >= 20:
                Select(select_bank).select_by_index(bank_index)
                break
            else:
                print(f"进程{thread_index} 没有营业厅有纪念币了...")
                break

3. 兑换时间

选择时间可以通过两次定位来实现,但是速度较慢且 Xpath 路径不好写,且有时会涉及到 frame ,此时需要切换 frame,比较麻烦。所以本文使用 js 来处理时间控件,实现原理为删除 input 的 readonly 属性,直接输入日期。

# general_settings.py

# 兑换时间
coindate = ""  # 按照'年-月-日'输入日期,例如:'2023-01-01'
# main.py

def coin_date(coindate: str):
    """
    选择兑换时间
    :param coindate: 兑换时间
    :return: None
    """
    js_date = 'document.getElementById("coindate").removeAttribute("readonly");'  # 执行 js 代码去除 readonly 属性
    browser.execute_script(js_date)
    browser.find_element(By.ID, 'coindate').clear()  # 清除输入框
    browser.find_element(By.ID, 'coindate').send_keys(coindate)  # 输入日期

至此,基本的 Selenium 自动化已经完成。接下来,就是本文的核心:图像验证码与短信验证码。

Part II:图形验证码

1. 图形验证码数据集获取

既然选择用深度学习识别验证码,首先就是获取验证码数据集。

Selenium 自动化测试之纪念币预约,selenium,自动化,python,mysql,android

在预约界面查找元素可知验证码的 src,刷新后会显示不同的图形验证码,这样图形验证码的数据源就搞定了。下面就是使用 requests 库爬取图形验证码,并以二进制方式写入到本地文件,这里一共爬取 3000 张验证码。

# captcha_get.py

import time
import os
import requests


url = f'https://eapply.abchina.com/coin/Helper/ValidCode.ashx'

if not os.path.exists('./pic_captcha'):
    os.makedirs('./pic_captcha')

for index in range(3000):
    file = f'./pic_captcha/captcha_{index}.png'
    re = requests.get(url)
    with open(file, 'wb') as f:
        f.write(re.content)
    print(f'captcha_{index} finished...')
    time.sleep(0.1)

但由于这些验证码之后还需要进行标注,比较麻烦,特此将我用 2captcha 标注好的 3000 张验证码贴出来,格式为 " 验证码_piccaptcha+hash.png "。(别问我为什么不直接用 2captcha,因为一个验证码要 5 s,这速度还不如直接手动输入)

Selenium 自动化测试之纪念币预约,selenium,自动化,python,mysql,android

下载数据集 - Kaggle

下载数据集 - AliCloud

2. 训练模型

下面介绍本文采用的 CNN 模型 ocr_jasper,基于 mobildenetv2 修改而来,下图为网络结构。

Selenium 自动化测试之纪念币预约,selenium,自动化,python,mysql,android

训练代码在此就不详细说明了,详情可看仓库中 ” ocr_jasper_train “ 内的 README.md 。训练完成后,会得到 model.onnxcharsets.json 两个文件,分别为模型文件和字符集文件,这两个文件需配合 ocr_jasper 库使用。

3. 获取页面中图形验证码

上文爬取验证码时提到过,图形验证码的数据源是一条链接,所以无法直接通过链接直接下载图形验证码,故对图形验证码的元素进行截图并保存,方便 ocr_jasper 调用。

# main.py

def pic_captcha_save():
    """
    定位验证码进行截图
    :return: None
    """
    captcha_img = browser.find_element(By.XPATH, '//*[@id="piccaptcha"]')  # 要截图的元素
    x, y = captcha_img.location.values()  # 坐标
    h, w = captcha_img.size.values()  # 宽高
    image_data = browser.get_screenshot_as_png()  # 把截图以二进制形式的数据返回
    screenshot = Image.open(BytesIO(image_data))  # 以新图片打开返回的数据
    result = screenshot.crop((x, y, x + w, y + h))  # 对截图进行裁剪
    result.save(f'./Captcha/pic_captcha_thread{thread_index}.png')

4. 使用 ocr_jasper 识别图形验证码

现在,就可以通过调用 ocr_jasper 来对图形验证码进行识别了,ocr_jasper 可以从本文的仓库中获取,在 CMD 或 Anaconda Prompt 中运行:

pip install {ocr_jasper} # 将 {ocr_jasper} 替换为 ocr_jasper 的相对或绝对路径 

接下来就可以在代码中调用 ocr_jasper 了,将代码中import_onnx_pathcharsets_path修改为训练好的模型和字符集文件的相对或绝对路径,默认放在项目根目录下的 Models 文件夹中。

# main.py

def pic_captcha_recognition():
    """
    使用 ocr_jasper 识别图形验证码
    :return: None
    """
    ocr_pic = ocr_jasper.OCR(import_onnx_path='./Models/model.onnx',charsets_path="./Models/charsets.json")
    with open(f'./Captcha/pic_captcha_thread{thread_index}.png', 'rb') as f:
        image = f.read()
    captcha_recognized = ocr_pic.classification(image)
    browser.find_element(By.XPATH, '//*[@id="piccode"]').send_keys(captcha_recognized)  # 验证码输入框
        
        
def get_text_captcha():
    """
    获取短信验证码
    :return: None
    """
    browser.find_element(By.XPATH, '//*[@id="sendValidate"]').click() 

5. 判断图形验证码是否识别正确

有时 ocr 会抽风,无法正确识别图形验证码,在此添加一个函数来判断是否识别正确。当识别错误时,id 为 errorCaptchaNo的元素会变成 ” 图形验证码错误 “;识别正确时,会变为 ” 短信验证码已发送成功 “,所以可以通过该元素文本长度来判断图形验证码是否识别正确。又因为captcha_success变量会跨函数多次调用,故将其定义为全局变量。

# main.py

def captcha():
    """
    判断图形验证码是否正确
    :return: None
    """
    global captcha_success
    while True:
        pic_captcha_save()
        time.sleep(1)
        pic_captcha_recognition()
        get_text_captcha()
        time.sleep(0.5)
        is_captcha_error = browser.find_element(By.XPATH, '//*[@id="errorCaptchaNo"]').text
        if len(is_captcha_error) == 7:
            browser.find_element(By.XPATH, '//*[@id="piccaptcha"]').click()  # 重新获取验证码
            browser.find_element(By.XPATH, '//*[@id="piccode"]').clear()
        elif len(is_captcha_error) == 10:
            captcha_success = True
            break

短信验证码与多线程并发

短信验证码与多线程并发内容可见我的个人博客

  • 个人博客:JasperX’s Blog
  • 项目仓库:Github

以上就是本次自动化测试预约纪念币的所有内容了,如果你喜欢我,欢迎关注我的 CSDN、知乎,或者在下方留下你的评论,Bye!

遵守协议:BY-NC-ND文章来源地址https://www.toymoban.com/news/detail-685807.html

到了这里,关于Selenium 自动化测试之纪念币预约的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【自动化测试】Java+Selenium自动化测试环境搭建

    本主要介绍以Java为基础,搭建Selenium自动化测试环境,并且实现代码编写的过程。 1.Selenium介绍 Selenium 1.0 包含 core、IDE、RC、grid 四部分,selenium 2.0 则是在两位大牛偶遇相互沟通决定把面向对象结构化(OOPP)和便于编写代码的各自思想予以整合后形成的新工具,也就是我们所

    2024年02月11日
    浏览(53)
  • JavaScript+Selenium自动化测试_selenium和js能一起做自动化测试

    var webdriver = require(‘selenium-webdriver’), By = webdriver.By, until = webdriver.until; var driver = new webdriver.Builder() .forBrowser(‘chrome’) .build(); driver.get(‘https://www.baidu.com’); driver.findElement(By.id(‘kw’)).sendKeys(‘webdriver’); driver.findElement(By.id(‘su’)).click(); driver.wait(until.titleIs(‘webdriver_百度

    2024年04月25日
    浏览(46)
  • 自动化测试介绍、selenium用法(自动化测试框架+爬虫可用)

    1、什么是自动化测试? 程序测试程序、代码代替思维、脚本代替人工 核心:质量和效率 作用:降低成本、节省人力时间、推动CI和DevOps、准确性和可靠性、模拟人工难以实现的手段、快速持续迭代发布能力、衡量产品的质量、提升测试效率、提高测试覆盖率 2、手工测试

    2024年03月08日
    浏览(81)
  • 自动化测试之web自动化(Selenium)

     🔥 交流讨论: 欢迎加入我们一起学习! 🔥 资源分享 : 耗时200+小时精选的「软件测试」资料包 🔥  教程推荐: 火遍全网的《软件测试》教程   📢 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! yycnblog 自动化测试概念:让程序代替人为去验证程序功能的过程,本

    2024年03月15日
    浏览(72)
  • 测开 - 自动化测试 selenium - 自动化概念 && 测试环境配置 - 细节狂魔

    自动化测试指 软件测试的自动化 ,在 预设状态下 运行应用程序或者系统. 预设条件 包括正常和异常 ,最后评估运行结果。   自动化测试,就是 将人为驱动的测试行为转化为机器执行的过程。 【机器 代替 人工】 自动化测试 包括UI自动化,接口自动化,单元测试自动化。

    2024年02月02日
    浏览(105)
  • Selenium+python怎么搭建自动化测试框架、执行自动化测试用例、生成自动化测试报告、发送测试报告邮件

    本人在网上查找了很多做自动化的教程和实例,偶然的一个机会接触到了selenium,觉得非常好用。后来就在网上查阅各种selenium的教程,但是网上的东西真的是太多了,以至于很多东西参考完后无法系统的学习和应用。 以下整理的只是书中自动化项目的知识内容,介绍怎么搭

    2024年02月05日
    浏览(67)
  • 自动化测试:5分钟了解Selenium以及如何提升自动化测试的效果

    在快节奏的技术世界里,自动化测试已经成为确保 Web 应用程序质量和性能的重要手段。自动化测试不仅加快了测试过程,还提高了测试的重复性和准确性。Selenium,作为领先的自动化测试工具之一,为测试人员提供了强大的功能来模拟用户在 Web 浏览器中的行为。在本文中

    2024年01月20日
    浏览(45)
  • 【软件测试/自动化测试】WebDriver+Selenium实现浏览器自动化

    前言 使用场景 原理 环境准备  开发 First Script WebDriver API 浏览器 元素 总结 Selenium是一款可以自动化操作浏览器的开源项目,最初的目的是浏览器功能的自动化测试,但是随着项目的发展,人们根据它的特性也用来做一些更多的有意思的功能而不仅仅是UI的自动化测试工具。

    2024年02月08日
    浏览(82)
  • 自动化测试-Selenium

    目录 什么是自动化测试 Selenium介绍 Selenium是什么 Selenium特点 Selenium工作原理 Selenium+Java环境搭建 1.下载chrome浏览器,查看版本号. 2.下载chrome浏览器驱动 3.配置环境变量 4.创建java项目,在pom文件中添加依赖 5. 验证环境是否搭建成功 Selenium常用API的使用 定位元素findElement css定位

    2024年02月16日
    浏览(40)
  • 自动化测试selenium

    将人工的测试手段进行转换,让代码去执行。 自动化分类: 单元测试 接口测试 UI自动化测试 selenium 是什么 selenium 是web应用中基于UI的自动化测试框架。 selenium 特点 支持多平台、多浏览器、多语言、有丰富的API 工作原理 定位元素 定位元素: findElement 通过CSS 选择器查找定

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包