python appium操作app

环境配置

参考文章:
python鬼才利用appium实现手机APP自动化!

下载源参考:
win10环境下,appium和python3的安装和配置

node.js下载:
官网

jdk下载:
华军软件园

android下载:http://tools.android-studio.org/index.php/sdk/

appium下载:
下载之家 Appium 官方版v1.8.0

app页面元素的有哪些属性,参考:
python+appium获取元素属性值

我安装的时候碰到一个坑:就是jdk、Android-sdk的环境变量配置与python的配置模式不一样。
生产使用了逍遥多开模拟器,该app使用默认Android5版本时,运行不成功,尝试了Android7和Android4.4维护版,最终只能在4.4版本上运行成功。

遇到的问题:

  1. 当app在模拟器上运行不成功,可能是Android版本的问题,尝试其它版本可能会成功。
  2. Android4.4维护版,对应的Android manager 是4.4.2版本(4.4.2w版本会失败)。
  3. 卡顿的问题,进行性能配置,渲染配置可能会好些,以及分辨率设置。

实际操作

以下是写的一个简单操作类:

# -*- coding: UTF-8 -*-
import copy
from appium import webdriver

class AppDriver(object):
    def __init__(self, platformName, deviceName, platformVersion, appPackage, appActivity, host, port):
        self.driver = None
        self.device_name = deviceName
        self.platform = platformName
        self.platform_version = platformVersion
        self.app_package = appPackage
        self.app_activity = appActivity
        self.host = host
        self.port = port
        self.create_driver()
        self.x = self.driver.get_window_size()["width"]
        self.y = self.driver.get_window_size()["height"]

    def create_driver(self):
        options = {
            'platformName': self.platform,
            'deviceName': self.device_name,
            'platformVersion': self.platform_version,
            'appPackage': self.app_package,
            'appActivity': self.app_activity
        }
        self.driver = webdriver.Remote(f'http://{self.host}:{self.port}/wd/hub', options)

    def get_page_elements_id(self, need_print=False):
        elements = self.driver.find_elements_by_xpath('//*')
        id_dict = {}
        all_text = []
        for element in elements:
            if need_print:
                print('======')
                print(element.get_attribute('className'))
                print(element.text)
                print(element.get_attribute('name'))
                print(element.get_attribute('resourceId'))
                print('=======')
            if element.text:
                all_text.append(element.text)

            resource_id = element.get_attribute('resourceId')
            if resource_id and element.text:
                id_dict[resource_id] = element.text

        return id_dict, all_text

    def swipe_down(self, start_y=0.6, stop_y=0.9, duration=200):
        # 按下手机屏幕,向下滑动
        # 注意,向下滑时,x轴不变,要不然就变成了斜向下滑动了
        # @duration:持续时间

        x1 = int(self.x * 0.5)
        y1 = int(self.y * start_y)
        x2 = int(self.x * 0.5)
        y2 = int(self.y * stop_y)
        # print x1,y1,x2,y2
        self.driver.swipe(x1, y1, x2, y2, duration)

    def swipe_left(self, star_x=0.75, stop_x=0.25, duration=300):
        # 按下手机屏幕,向左边滑动
        # 注意,向左边滑时,y轴不变
        # @duration:持续时间
        x1 = int(self.x * star_x)
        y1 = int(self.y * 0.5)
        x2 = int(self.x * stop_x)
        y2 = int(self.y * 0.5)
        # print x1,y1,x2,y2
        self.driver.swipe(x1, y1, x2, y2, duration)

    def swipe_right(self, star_x=0.25, stop_x=0.75, duration=300):
        # 按下手机屏幕,向右边滑动
        # 注意,向左边滑时,y轴不变
        # @duration:持续时间
        x1 = int(self.x * star_x)
        y1 = int(self.y * 0.5)
        x2 = int(self.x * stop_x)
        y2 = int(self.y * 0.5)
        # print x1,y1,x2,y2
        self.driver.swipe(x1, y1, x2, y2, duration)

    def swipe_up(self, start_y=0.9, stop_y=0.6, duration=300):
        # 按下手机屏幕,向上滑动
        # 注意,向上滑时,x轴不变,要不然就变成了斜向下滑动了
        # @duration:持续时间
        x1 = int(self.x * 0.5)
        y1 = int(self.y * start_y)
        x2 = int(self.x * 0.5)
        y2 = int(self.y * stop_y)
        # print x1,y1,x2,y2
        self.driver.swipe(x1, y1, x2, y2, duration)

    def find_element_by_text(self, text):
        return self.driver.find_element_by_android_uiautomator(f'text(\"{text}\")')

    def click_text(self, text):
        try:
            node = self.find_element_by_text(text)
        except:
            node = self.find_element_by_text_startswith(text)
        node.click()
        return 1

    def find_id(self, resource_id):
        return self.driver.find_element_by_id(resource_id)

    def click_id(self, resource_id):
        self.find_id(resource_id).click()

    def get_text_of_id(self, resource_id):
        return self.find_id(resource_id).text

    def find_element_by_text_startswith(self, text):
        loc = f'new UiSelector().textStartsWith("{text}")'
        return self.driver.find_element_by_android_uiautomator(loc)

    def send_key_to_element_by_id(self, resource_id: str, text: str):
        node = self.driver.find_element_by_id(resource_id)
        node.send_keys(text)

    def wait(self, sec):
        self.driver.implicitly_wait(sec)

    def close(self):
        self.driver.close_app()


# adb命令
# adb shell pm list packages -f  # 获取app名称列表
# adb shell
# dumpsys activity | grep mFocusedActivity  获取 appPackage和 appActivity
# :/data/app/com.xmeng.ued-1.apk=com.xmeng.ued
desired_caps = {
    'platformName': 'Android',
    'deviceName': 'emulator-5554',
    'platformVersion': '4.4',
    'appPackage': 'com.xmeng.ued',
    'appActivity': 'XMMainActivity',
    'host': '127.0.0.1',
    'port': 4723, # appium端口
}
driver = AppDriver(**desired_caps)
driver.click_text('北京')
# 打印页面元素
driver.get_page_elements_id(need_print=True)
driver.click_id('com.xmeng.ued:id/function4')


def find_destination_text(resource_id):
# 获取目标文本,未成功就向上滑动直到成功
    res = ''
    while not res:
        try:
            res = driver.get_text_of_id(resource_id)
            return res
        except:
            driver.swipe_up()


# 职业介绍数据
def find_zyjs_data(data):
	# 获取某个页面的指定数据
    driver.click_text('职业介绍')
    tasks = {
        'job_define': 'com.xmeng.ued:id/jabDefinitionTV',
        'job_intro': 'com.xmeng.ued:id/job_introduce',
        'job_task': 'com.xmeng.ued:id/jobTask',
        'job_learn_skill': 'com.xmeng.ued:id/joblearnskill',
        'job_skill': 'com.xmeng.ued:id/jobskill',
    }
    for k, task in tasks.items():
        if k == 'job_task':
            res = find_destination_text(task)
            if '工作考核要求' in res:
                data['job_responsibility'] = res.split('工作考核要求:')[0]
                data['job_require'] = '工作考核要求:' + res.split('工作考核要求:')[1]
            else:
                data['job_responsibility']=''
                data['job_require']=''
        else:
            data[k] = find_destination_text(task)
    driver.click_text('返回')
    return data


def click_text_util_success(text):
    res = ''
    times = 0
    while not res:
        try:
            res = driver.click_text(text)
        except:
            if times < 10:
                driver.swipe_up()
                # 怎么判断是否滑动到底部 ,通过两次页面的元素一样,但比较耗时
            else:
                driver.swipe_down()
            times += 1
            if times > 22:
                print('==========', text)
                break


def find_one_cate(cate):
    function4 = 0
    while not function4:
        try:
            driver.click_id('com.xmeng.ued:id/function4')
            function4 = 1
        except:
            driver.click_text('返回')
    driver.click_text(cate)

    data = {
        'big_profession': '',
        'profession': '',
        'job_define': '',
        'job_intro': '',
        'job_responsibility': '',
        'job_require': '',
        'job_learn_skill': '',
        'job_skill': '',
    }
    for kind_name in ALL_KINDS[cate]:
        # 去重
        hash_txt = redis_cli.hash_md5(kind_name)
        if redis_cli.exist(hash_txt):
            continue
        click_text_util_success(kind_name)
        driver.wait(2)
        kind_data = find_zyjs_data(data=copy.deepcopy(data))
        kind_data['big_profession'] = cate
        kind_data['profession'] = kind_name
        # 保存数据
        mysql_cnn.save_many(save_sql, save_data=[list(kind_data.values())])
        redis_cli.add(hash_txt)
    print(f'完成职业类:{cate} 数据采集')


def main():
    for cate in cate_list:
        try:
            find_one_cate(cate)
        except:
            pass
    driver.close()

if __name__ == '__main__':
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值