python+appium自动化测试获取短信+图片验证码

该网站上更新文章有延迟,如需查看关于python+appium文章,请前往testhome关注我哦。https://testerhome.com/topics/27802

本篇文章主要讲述的是如何自动获取短信验证码和如何自动获取图片验证码,并写入到对应的输入框中(以下均使用微博的找回密码作为示例)

获取短信验证码的方法有三种,如下所示:

在手机的通知栏中获取短信内容

通过监控手机日志获取短信验证码

通过redis获取短信验证码

以下只写出第一种在通知栏中获取短信内容的方法,后续两种方法会在后面进行分享。

获取图片验证码的方法:

通过百度的OCR文字识别,进行识别获取图片中的字母、文字或数字验证码。

一、获取短信验证码

方法:发送短信验证码后,打开手机的通知栏,定位短信内容,将定位到的内容填入到验证码输入框中,核心代码为:

# 打开手机通知栏

self.driver.open_notifications()

# 获取定位短信内容(封装了元素定位,详细操作可见上一篇PO模式封装的博客)

message = self.find_element(self._message_content)

# 将短信内容转换为text文本

message_content = message.text

# 通过正则匹配短信内容中的验证码(使用r前缀可以自动转义,不需要手动转换字符串,6表示6位数字的验证码)

ver_code = re.findall(r'[\\d]{6}', message_content)

# 关闭通知栏(下面方式为点击手机返回键来关闭通知栏)

self.driver.press_keycode(4)

# 自动填入验证码(将获取到的验证自动填入到验证码输入框中)

self.input_verification_code(ver_code)

注意:由于我的类中继承了BasePage类,而BasePage类中声明driver是属于WebDriver库(WebDriver库属于Selenium框架),而以上代码中调用的open_notifications()和press_keycode()方法是属于webdriver库(webdriver库属于appium框架),所以需要在该类中导入webdriver类,并在类中将driver声明为webdriver,否则会出现如下图所示错误:

导入和声明的方式如下:

# 导入webdriver

from appium import webdriver

from page.base_page import BasePage

class PhoneLoginPage(BasePage):

# 声明

driver: webdriver = None

二、申请百度OCR识别接口,下载对应语言的SDK文件

在调用百度OCR图片识别前,需要先申请百度通用文字识别接口,申请方法如下:

1.登录百度AI平台,申请百度通用文字识别接口,免费激活AI平台的使用权限

百度AI平台网址:https://ai.baidu.com/

进入开放能力→文字识别→通用文字识别,如下图:

点击立即使用:

创建应用:

创建成功后进入管理应用,能查看创建的应用AppID、API Key、Secret Key,如下图:

2. 查看适用不同平台/语言/功能的SDK

文字识别链接:https://ai.baidu.com/sdk#ocr

下载需要语言的SDK:

我使用的是python语言,所以下载的是对应的Python SDK(支持python版本:2.7.+,3.+),下载完成后,安装方式有两种:

①已经安装pip,打开命令提示符,输入以下命令即可

pip install baidu-aip

②已经安装setuptools,打开命令提示符,输入以下命令即可

python setup.py install

出现下图表示安装成功:

3.文字识别接口说明(参考文档)

文字识别接口说明链接:https://ai.baidu.com/ai-doc/OCR/7kibizyfm

或者可以通过上面图片(下载所需语言的SDK)→使用说明→接口说明进入(后续会使用到这篇文档,建议在写脚本前先阅读)

三、图片验证码识别

方法:在工程中自动创建一个存放图片的文件夹,再定位图片验证码的控件,截取图片验证码,将截取到的图片使用自动生成的规则的文件名,保存在创建的图片文件夹内,存储后通过百度的OCR文字识别,获取到保存的截图,进行文字识别,再将识别的结果输出到验证码输入框内

注意:

问:为什么要将图片有规则的命名?

答:方便后续查找核对

问:为什么截图保存不能保存在本地磁盘内,而是保存在本地工程目录下方?

答:如果保存图片时使用的是本地固定的磁盘,那别人使用你的代码时就需要修改保存的路径,如果保存在本地工程目录下方,别人就不需要手动创建文件夹,直接运行代码就能自动在工程目录下生成文件夹

1.screenshot.py— 验证码截图,并通过特定的规律保存在特定的文件夹中

import time

from common.image_recognition import ImageRecognition

from page.base_page import BasePage

class Screen(BasePage):

    # 图片验证码输入框

    _img_check_code = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.webkit.WebView/android.webkit.WebView/android.widget.Image"

    # 截取页面中特定区域的图片

    def get_part_screen(self):

        # 截图将图片保存至固定的位置

        img_folder = 'E:\\study\\Fork\\Weibo_Demo\\Weibo\\image\\'

        # 截图的文件名组成

        times = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))

        # 图片存储位置+文件名

        screen_save_path = img_folder + times + '.png'

        # 截取特定位置的图片,并保存在已定义的存储位置和规定的文件名

        self.find_xpath(self._img_check_code).screenshot(screen_save_path)

        # 实例化ImageRecognition,传入需要识别的图片位置

        ir = ImageRecognition(screen_save_path)

        a = ir.ocr()

return a

2.image_recognition.py — 调用百度OCR文字识别

from aip import AipOcr

class ImageRecognition:

    # 初始化path,定义为字符类型

    def __init__(self, path: ''):

        self.path = path

    # 你的 APPID AK SK

    APP_ID = '123456'

    API_KEY = 'fydhafbuebfuebiufwbiufe'

    SECRET_KEY = 'difwebfubweufbweffefefefefefef'

    client = AipOcr(APP_ID, API_KEY, SECRET_KEY)

    # 配置参数,识别到图片内容时,需要输出的内容

    def get_garameter(self):

        options = {

            # 识别语言类型,默认为CHN_ENG

            "language_type": "ENG",

            # 是否检测图像朝向,默认不检测,即:false

            "detect_language": "true"

            # 是否返回识别结果中每一行的置信度

            # "probability": "true"

        }

        return options

    # 打开文件

    def get_file_content(self, file_path):

        with open(file_path, 'rb') as fp:

            return fp.read()

    # 需要识别的图片的路径

    def get_image(self):

        return self.get_file_content(self.path)

    # 调用百度ocr接口,进行精准识别

    def ocr(self):

        image_content = self.client.basicAccurate(self.get_image()), self.get_garameter()

        return image_content

注意:在调用百度OCR识别需要在运行环境(工程)下安装baidu-aip,安装步骤如下:

打开Setting→Python Interpreter,点击+号

搜索输入:baidu-aip,点击搜索结果列表中第一个,点击install package

在Setting→Python Interpreter页面出现下图,表示安装成功

3.retrieve_password_page.py — 对获取到的图片验证码解析

from time import sleep

from selenium.webdriver.common.by import By

from common.screenshot import Screen

from page.base_page import BasePage

class RetrievePasswordPage(BasePage):

# 初始化,用于实例化Screen类

    def __init__(self, driver):

        super().__init__(driver)

        self.screen = Screen(driver)

# 自动获取图片验证码中的内容

    def auto_get_check_code(self, telephone):

        self.input_telephone(telephone)

        # 获取图片验证码,获取到的是元组

        check_code_tuple = self.screen.get_part_screen()

        print(check_code_tuple)

        # 在元组中提取第一个数据(元组下标位置从0开始),获取到的数据为字典(字典是一组键值对)

        check_code_list = check_code_tuple[0]

        print(check_code_list)

        # 在字典中提取第三个数据'words_result',获取到的数据为列表

        word_result = check_code_list['words_result']

        # 判断获取到的列表的值是否为空,为空则在列表中自定义一个字典“word_result”的值

        if word_result:

            print(word_result)

        else:

            word_result = [{'words': 'F3HA'}]

        print(word_result)

        # 在列表中提取一个数据,获取到的数据是字典

        dic_words = word_result[0]

        print(dic_words)

        # 在字典中输出"words"

        word = dic_words['words']

        print(word)

        self.input_image_check_code(word)

        self.find_xpath(self._btn_confirm).click()

        sleep(1)

说明:由于通过百度OCR识别到的内容是一个字典,如下:

({'log_id': 6483429546783692489, 'words_result_num': 1, 'words_result': [{'words': ' F3H'}]}, {'language_type': 'ENG', 'detect_language': 'true'})

通过处理,将以上内容转换为JSON格式,转换后如下图显示:

我们需要获取的是words,所以需要一层一层的获取元素,具体的获取方式是请查看python的字典、元组、列表,可参考菜鸟教程:https://www.runoob.com/python3/python3-dictionary.html

注意:经实验,该种方式对于比较奇葩的图片验证码识别概率低,识别中规中矩的图片验证码成功率较高

4.testcase.py— 测试用例

# 找回密码测试用例脚本

import pytest

from common.init import AppStart

class TestRetrievePassword:

    def setup(self):

        self.retrievepassword = AppStart.start().enter_retrieve_password()

    # 自动获取图片验证码

    def test_auto_get_check_code(self):

        telephone = "18056120351"

        self.retrievepassword.auto_get_check_code(telephone)

        assert self.retrievepassword.get_phone_and_check_code_tips() == "请输入正确的验证码"

    def teardown(self):

        AppStart.quit()

以上内容有不正确的地方,欢迎大家提出来,谢谢!(由于该篇文章的代码结构较不清晰,可查看下面这篇博客:https://juejin.cn/post/6914226020899880967)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容