Python + selenium QQ注册界面的半自动化测试

当时选择题目的时候感觉不需要自己做程序应该会很简单就选了,然后在输入手机号后弹出了验证码发送按钮,然后点击验证码发送按钮会出现让你滑动滑块的人机校验…以我现在的水平是不可能自动完成市面上存在的人机校验的。所以
1、建议我们跳过这个部分,也就是直接不点击获取验证码。
2、执行到这一步“暂停”程序,手动操作完成后再继续程序。

操作思路

1、Pycharm中创建一个项目,下载selenium插件。
2、选择一个电脑上存在的浏览器,下载它的web driver驱动,这个驱动是selenium操作浏览器的基础。
3、准备一个txt当作输入,程序在读取这个文件中的测试用例后依次执行每一条用例,再将结果输出到另一个txt。
4、编写程序并运行。

下载selenium

1、PyCharm的控制台(terminal)(alt+F12)中输入:
pip install selenium
(你也可以打开cmd来输入这段代码安装)
2、PyCharm打开file -> setings… -> Project: … -> Python Interpreter,点击“+”号增加一个Package,搜索selenium并install Package。
在这里插入图片描述

下载浏览器驱动

这里我以windows普遍都有的Microsoft Eage为例。
1、打开你的浏览器设置查看版本,设置 -> 关于Microsoft Eage
在这里插入图片描述
一般都是会自动更新到最新的版本的。
2、下载驱动
网址:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
请添加图片描述
选择符合自己电脑架构的版本。

编写程序

在project创建完毕后会自动生成一个main.py文件,那么我们可以直接使用它来编写。
在这里插入图片描述
改成我们需要的样子。
在这里插入图片描述

使用selenium

打开浏览器
from selenium import webdriver
from selenium.webdriver.edge.service import Service

def test():
    # 开启页面
    option = webdriver.EdgeOptions()
    option.add_experimental_option("detach", True)  # 页面不自动关闭

    s = Service("D:\\browser\Microsoft_Eage\edgedriver\msedgedriver.exe")  # 驱动位置
    driver = webdriver.Edge(service=s, options=option)  # 设置浏览器驱动
    driver.get("https://ssl.zc.qq.com/v3/index-chs.html")  # 打开的网址


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    test()

此处option的用处是使页面不自动关闭,当时不使用option直接开启发现会闪退,可能其他人没有这个问题。
Service是新整合的api,使用WebDriver driver=new EageDriver()可能因为是旧版本报错。

此时直接运行main.py就能打开浏览器qq注册页面。

在输入框填写数据

以输入昵称为例,
找到input框的位置右键复制XPath(这里是建议使用XPath来定位标签)
在这里插入图片描述
回到PyCharm先引入By

from selenium.webdriver.common.by import By

使用这段代码,将复制的XPath放入value中,这里它是//*[@id=“nickname”],“芜湖”是输入的内容。

driver.find_element(by=By.XPATH, value='//*[@id="nickname"]').send_keys("芜湖")  # 输入昵称
获取提示信息

还是以昵称输入框为例,它为空的时候会提示昵称不能为空(刚进入页面时它是空的但不会有提示,可以点击注册按钮显示),此时找到显示提示的标签复制XPath就行。定位标签后加上.text获取标签中的内容。

# 昵称输入提示
nickname_error = driver.find_element(
    by=By.XPATH,
    value='/html/body/div[3]/div[2]/div[1]/form/div[1]/div[3]/div'
).text
点击操作
driver.find_element(by=By.XPATH, value='//*[@id="get_acc"]').click()  # 点击注册按钮
截图并保存
# 截图保存到项目文件夹
# os.path.dirname(__file__)是获取当前项目地址
# screenshots为你想要创建的文件夹名
screenshot_dir = os.path.join(os.path.dirname(__file__), "screenshots")  
# 如果不存在你所说的这个文件夹就创建一个
if not os.path.exists(screenshot_dir):
    os.makedirs(screenshot_dir)
# time.time()是获取当前时间,防止截图文件名重复
driver.save_screenshot(os.path.join(screenshot_dir, "%s.png" % time.time()))

在使用time之前需要引入

import time

文件操作

import os.path

前面演示的内容只能进行一次输入,但是我们有多个测试用例,所以往往需要循环放入测试数据,你可以把所有测试用例写在一个数组里读取,但还是建议新建一个txt文件来存放所有的测试用例。
首先新建一个input.txt文件,你可以自己定义输入输出规则,这里展示我的输入文件结构。
tip:1766666666本来是真实号码,这里演示用。
在这里插入图片描述以逗号分隔不同的测试输入。

# 读取测试用例
input_data = []
with open("input.txt", encoding="utf-8") as f:
    line = f.readline().strip()  # 获取第一行 .
    input_data.append(line)
    while line:
        line = f.readline().strip()
        # 这里是我遇到的一个bug,读取到最后一行以后还会多读取一行空的。
        # 添加这个判断也可以忽略掉中间存在的空行
        if line != "":  
            input_data.append(line)

这是获取每一行存入数组,之后还要将每一行的数据按逗号分隔后使用。

output_data = []  # 设置输出数组
for index, line in enumerate(input_data):
    if index == 0:  # 第一行不是数据
        output_data.append(line + " 结果")
        continue
    data_list = line.split(',')  # 当前这个循环的数据数组 split以空格分隔

输出文件结构:
在这里插入图片描述

当一个循环内测试结束后将所有提示串起来存入

# 存入结果数组
line = line + " " + nickname_error + password_error + phone_error + code_error + service_record_error
if line == line + " ":
    line += '成功'
output_data.append(line)
with open("output.txt", "w", encoding="utf-8") as f:  # w是指从头开始写入,会覆盖原来的信息,不覆盖换成a
    for line in output_data:
        print(line, file=f)

关于文件操作的参考:
(25条消息) python读取txt文件(多种方法)_总裁余(余登武)的博客-CSDN博客_python读取txt文件
(25条消息) python输出为txt文件_仰望星空007的博客-CSDN博客_python输出txt文件
(25条消息) python报错io.UnsupportedOperation: not writable_JJWang_7978的博客-CSDN博客
Python清空文本内容的两种方法 - profesor - 博客园 (cnblogs.com)

源码

跳过验证码版本

输入的验证码为“<空>”或“(正确)”时直接跳过。
tip:勾选用户协议的两个状态它会选择显示不同的标签图片来表示,selenium点击不存在的标签会报错,所以需要在点击之前加上判断。

# main.py
# This is a sample Python script.

# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
import os.path
import time

from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.common.by import By
import temporary


def test():
    # 读取测试用例
    input_data = []
    with open("input.txt", encoding="utf-8") as f:
        line = f.readline().strip()  # 获取第一行
        input_data.append(line)
        while line:
            line = f.readline().strip()
            if line != "":
                input_data.append(line)
    # 测试
    output_data = []  # 设置输出数组

    # 开启页面
    option = webdriver.EdgeOptions()
    option.add_experimental_option("detach", True)  # 页面不自动关闭

    s = Service("D:\\browser\Microsoft_Eage\edgedriver\msedgedriver.exe")  # 驱动位置
    driver = webdriver.Edge(service=s, options=option)  # 设置浏览器驱动
    driver.get("https://ssl.zc.qq.com/v3/index-chs.html")  # 打开的网址

    for index, line in enumerate(input_data):
        if index == 0:
            output_data.append(line + " 实际结果比对")
            continue

        data_list = line.split(",")
        print(data_list)
        if data_list[0] != '<空>':
            driver.find_element(by=By.XPATH, value='//*[@id="nickname"]').send_keys(data_list[0])  # 输入昵称
        if data_list[1] != '<空>':
            driver.find_element(by=By.XPATH, value='//*[@id="password"]').send_keys(data_list[1])  # 输入密码
        if data_list[2] != '<空>':
            driver.find_element(by=By.XPATH, value='//*[@id="phone"]').send_keys(data_list[2])  # 输入手机号
            # temporary.temporary()
        if data_list[3] != '<空>' and data_list[3] != '(正确)':
            driver.find_element(by=By.XPATH, value='//*[@id="code"]').send_keys(data_list[3])  # 输入验证码
        else:
            driver.find_element(by=By.XPATH, value='//*[@id="code"]').send_keys(data_list[3])  # 输入验证码
            driver.find_element(by=By.XPATH, value='//*[@id="code"]').clear()  # 这里输入再清除是为了让页面重新判断隐私政策的勾选
        if data_list[4] == '(勾选)' and driver.find_element(
                by=By.XPATH, value='/html/body/div[3]/div[2]/div[1]/form/div[8]/label/img[2]'
        ).value_of_css_property('display') != 'none':
            driver.find_element(
                by=By.XPATH, value='/html/body/div[3]/div[2]/div[1]/form/div[8]/label/img[2]').click()  # 勾选隐私政策
        elif data_list[4] == '(未勾选)' and driver.find_element(
                by=By.XPATH, value='/html/body/div[3]/div[2]/div[1]/form/div[8]/label/img[1]'
        ).value_of_css_property('display') != 'none':
            driver.find_element(
                by=By.XPATH, value='/html/body/div[3]/div[2]/div[1]/form/div[8]/label/img[1]').click()  # 取消勾选隐私政策
        driver.find_element(by=By.XPATH, value='//*[@id="get_acc"]').click()  # 点击注册按钮
        # 截图保存到项目文件夹
        screenshot_dir = os.path.join(os.path.dirname(__file__), "screenshots")
        if not os.path.exists(screenshot_dir):
            os.makedirs(screenshot_dir)
        driver.save_screenshot(os.path.join(screenshot_dir, "%s.png" % time.time()))
        # 昵称输入提示
        nickname_error = driver.find_element(
            by=By.XPATH,
            value='/html/body/div[3]/div[2]/div[1]/form/div[1]/div[3]/div'
        ).text
        print(nickname_error, end="")
        # 密码输入提示
        password_error = driver.find_element(
            by=By.XPATH, value='/html/body/div[3]/div[2]/div[1]/form/div[2]/div[4]/div'
        ).text
        print(password_error, end="")
        # 手机号输入提示
        phone_error = driver.find_element(
            by=By.XPATH, value='/html/body/div[3]/div[2]/div[1]/form/div[4]/div'
        ).text
        print(phone_error, end="")
        # 验证码输入提示
        code_error = driver.find_element(
            by=By.XPATH, value='/html/body/div[3]/div[2]/div[1]/form/div[6]/div[2]/div'
        ).text
        if data_list[3] == '(正确)':
            code_error = ''
        print(code_error, end="")
        # 隐私政策输入提示
        service_record_error = driver.find_element(
            by=By.XPATH, value='/html/body/div[3]/div[2]/div[1]/form/div[7]/div/div'
        ).text
        print(service_record_error)
        # 存入结果数组
        error = nickname_error + password_error + phone_error + code_error + service_record_error
        if error == '':
            error = "成功"
        if error == data_list[5]:
            line = line + " 通过"
        else:
            line = line + " 未通过"
        output_data.append(line)
        # 清空输入
        driver.find_element(by=By.XPATH, value='//*[@id="nickname"]').clear()
        driver.find_element(by=By.XPATH, value='//*[@id="password"]').clear()
        driver.find_element(by=By.XPATH, value='//*[@id="phone"]').clear()
        driver.find_element(by=By.XPATH, value='//*[@id="code"]').clear()
    with open("output.txt", "w", encoding="utf-8") as f:  # w是指从头开始写入,会覆盖原来的信息,不覆盖换成a
        for line in output_data:
            print(line, file=f)
    driver.quit()  # 关闭页面


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    test()

# See PyCharm help at https://www.jetbrains.com/help/pycharm/

暂停并手动操作

相当于在运行到输入手机号这一步以后它需要暂停让我们操作,我们手动操作完以后再给它一个信号让他继续运行。我暂时还没有直接暂停主进程的方法。并且在操作完以后它还得知道我们操作完了。最初的想法是在这一步之后创建一个按钮,并让主线程无限循环。但是我们在创建按钮之前需要创建一个窗口来放置按钮,然后我意外的发现创建一个窗口时主程序会暂停等待窗口运行直到关闭。
于是我另外创建了一个py文件来写创建窗口的方法。
在这里插入图片描述

import tkinter
from tkinter import *


def temporary():
    win = tkinter.Tk()  # 创建窗口
    win.title('暂停')  # 添加标题
    win.geometry('300x100')  # 设置窗口大小
    # 创建变量用于存放Button以及Button中的参数,root为根窗口,text为按钮上的文本内容,command=answer的作用是将按钮与函数绑定在一起
    win.mainloop()
    print("com")

然后把这个方法引入到main.py,并放在输入电话操作之后。

# main.py
import temporary
if data_list[2] != '<空>':
    driver.find_element(by=By.XPATH, value='//*[@id="phone"]').send_keys(data_list[2])  # 输入手机号
    temporary.temporary()  # 这里
if data_list[3] != '<空>' and data_list[3] != '(正确)':
    driver.find_element(by=By.XPATH, value='//*[@id="code"]').send_keys(data_list[3])  # 输入验证码

可以看一下效果,关闭暂停窗口它会继续运行。
在这里插入图片描述

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值