python爬虫之Appium 的使用

简介: 搭建appium环境,appium基本使用,API操作等等

Appium 是一个跨平台移动端自动化测试工具,可以非常便捷地为 iOS 和 Android 平台创建自动化测试用例。它可以模拟 App 内部的各种操作,如点击、滑动、文本输入等,只要我们手工操作的动作 Appium 都可以完成。在前面我们了解过 Selenium,它是一个网页端的自动化测试工具。Appium 实际上继承了 Selenium,Appium 也是利用 WebDriver 来实现 App 的自动化测试。对 iOS 设备来说,Appium 使用 UIAutomation 来实现驱动。对于 Android 来说,它使用 UiAutomator 和 Selendroid 来实现驱动。

Appium 相当于一个服务器,我们可以向 Appium 发送一些操作指令,Appium 就会根据不同的指令对移动设备进行驱动,完成不同的动作。

对于爬虫来说,我们用 Selenium 来抓取 JavaScript 渲染的页面,可见即可爬。Appium 同样也可以,用 Appium 来做 App 爬虫不失为一个好的选择。

下面我们来了解 Appium 的基本使用方法。

1. 本节目标

我们以 Android 平台的微信为例来演示 Appium 启动和操作 App 的方法,主要目的是了解利用 Appium 进行自动化测试的流程以及相关 API 的用法。

2. 准备工作

请确保 PC 已经安装好 Appium、Android 开发环境和 Python 版本的 Appium API,安装方法可以参考第 1 章。另外,Android 手机安装好微信 App。

3. 启动 APP

Appium 启动 App 的方式有两种:一种是用 Appium 内置的驱动器来打开 App,另一种是利用 Python 程序实现此操作。下面我们分别进行说明。

首先打开 Appium,启动界面如图。

image.gif 编辑

直接点击 Start Server 按钮即可启动 Appium 的服务,相当于开启了一个 Appium 服务器。我们可以通过 Appium 内置的驱动或 Python 代码向 Appium 的服务器发送一系列操作指令,Appium 就会根据不同的指令对移动设备进行驱动,完成不同的动作。启动后运行界面如图。

image.gif 编辑

Appium 运行之后正在监听 4723 端口。我们可以向此端口对应的服务接口发送操作指令,此页面就会显示这个过程的操作日志。

将 Android 手机通过数据线和运行 Appium 的 PC 相连,同时打开 USB 调试功能,确保 PC 可以连接到手机。

可以输入 adb 命令来测试连接情况,如下所示:

adb devices -l

如果出现类似如下结果,这就说明 PC 已经正确连接手机。

List of devices attached

2da42ac0 device usb:336592896X product:leo model:MI_NOTE_Pro device:leo

model 是设备的名称,就是后文需要用到的 deviceName 变量。我使用的是小米 Note 顶配版,所以此处名称为 MI_NOTE_Pro。

如果提示找不到 adb 命令,请检查 Android 开发环境和环境变量是否配置成功。如果可以成功调用 adb 命令但不显示设备信息,请检查手机和 PC 的连接情况。

接下来用 Appium 内置的驱动器打开 App,点击 Appium 中的 Start New Session 按钮。

image.gif 编辑

这时会出现一个配置页面。

image.gif 编辑

需要配置启动 App 时的 Desired Capabilities 参数,它们分别是 platformName、deviceName、appPackage、appActivity。

  • platformName,平台名称,需要区分是 Android 还是 iOS,此处填写 Android。
  • deviceName,设备名称,是手机的具体类型。
  • appPackage,APP 程序包名。
  • appActivity,入口 Activity 名,这里通常需要以。开头。

在当前配置页面的左下角也有配置参数的相关说明,链接是 https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md

我们在 Appium 中加入上面 4 个配置。

image.gif 编辑

点击保存按钮,保存下来,我们以后可以继续使用这个配置。

点击右下角的 Start Session 按钮,即可启动 Android 手机上的微信 App 并进入到启动页面。同时 PC 上会弹出一个调试窗口,从这个窗口我们可以预览当前手机页面,并可以查看页面的源码。

image.gif 编辑

点击左栏中屏幕的某个元素,如选中登录按钮,它就会高亮显示。这时中间栏就显示了当前选中的按钮对应的源代码,右栏则显示了该元素的基本信息,如元素的 id、class、text 等,以及可以执行的操作,如 Tap、Send Keys、Clear。

image.gif 编辑

点击中间栏最上方的第三个录制按钮,Appium 会开始录制操作动作,这时我们在窗口中操作 App 的行为都会被记录下来,Recorder 处可以自动生成对应语言的代码。例如,我们点击录制按钮,然后选中 App 中的登录按钮,点击 Tap 操作,即模拟了按钮点击功能,这时手机和窗口的 App 都会跳转到登录页面,同时中间栏会显示此动作对应的代码。

image.gif 编辑

接下来选中左侧的手机号文本框,点击 Send Keys,对话框就会弹出。输入手机号,点击 Send Keys,即可完成文本的输入。

image.gif 编辑

我们可以在此页面点击不同的动作按钮,即可实现对 App 的控制,同时 Recorder 部分也可以生成对应的 Python 代码。

下面我们看看使用 Python 代码驱动 App 的方法。首先需要在代码中指定一个 Appium Server,而这个 Server 在刚才打开 Appium 的时候就已经开启了,是在 4723 端口上运行的,配置如下所示:

server = 'http://localhost:4723/wd/hub'

用字典来配置 Desired Capabilities 参数,代码如下所示:

desired_caps = {

   'platformName': 'Android',

   'deviceName': 'MI_NOTE_Pro',

   'appPackage': 'com.tencent.mm',

   'appActivity': '.ui.LauncherUI'

}

新建一个 Session,这类似点击 Appium 内置驱动的 Start Session 按钮相同的功能,代码实现如下所示:

from appium import webdriver

from selenium.webdriver.support.ui import WebDriverWait


driver = webdriver.Remote(server, desired_caps)

配置完成后运行,就可以启动微信 App 了。但是现在仅仅是可以启动 App,还没有做任何动作。

再用代码来模拟刚才演示的两个动作:一个是点击 “登录” 按钮,一个是输入手机号。

看看刚才 Appium 内置驱动器内的 Recorder 录制生成的 Python 代码,自动生成的代码非常累赘,例如点击 “登录” 按钮的代码如下所示:

el1 = driver.find_element_by_xpath("/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.View/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.RelativeLayout/android.widget.Button[1]")

el1.click()

这段代码的 XPath 选择器路径太长,选择方式没有那么科学,获取元素时也没有设置等待,很可能会有超时异常。所以我们修改一下,将其修改为通过 ID 查找元素,设置延时等待,两次操作的代码改写如下所示:

wait = WebDriverWait(driver, 30)

login = wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/cjk')))

login.click()

phone = wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/h2')))

phone.set_text('18888888888')

综上所述,完整的代码如下所示:

from appium import webdriver

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC


server = 'http://localhost:4723/wd/hub'

desired_caps = {

   'platformName': 'Android',

   'deviceName': 'MI_NOTE_Pro',

   'appPackage': 'com.tencent.mm',

   'appActivity': '.ui.LauncherUI'

}

driver = webdriver.Remote(server, desired_caps)

wait = WebDriverWait(driver, 30)

login = wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/cjk')))

login.click()

phone = wait.until(EC.presence_of_element_located((By.ID, 'com.tencent.mm:id/h2')))

phone.set_text('18888888888')

一定要重新连接手机,再运行此代码,这时即可观察到手机上首先弹出了微信欢迎页面,然后模拟点击登录按钮、输入手机号,操作完成。这样我们就成功使用 Python 代码实现了 App 的操作。

4. API

接下来看看使用代码如何操作 App、总结相关 API 的用法。这里使用的 Python 库为 AppiumPythonClient,其 GitHub 地址为 GitHub - appium/python-client: Python language bindings for Appium,此库继承自 Selenium,使用方法与 Selenium 有很多共同之处。

初始化

需要配置 Desired Capabilities 参数,完整的配置说明可以参考 https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md,一般来说我们我们配置几个基本参数即可:

from appium import webdriver


server = 'http://localhost:4723/wd/hub'

desired_caps = {

   'platformName': 'Android',

   'deviceName': 'MI_NOTE_Pro',

   'appPackage': 'com.tencent.mm',

   'appActivity': '.ui.LauncherUI'

}

driver = webdriver.Remote(server, desired_caps)

这里配置了启动微信 App 的 Desired Capabilities,这样 Appnium 就会自动查找手机上的包名和入口类,然后将其启动。包名和入口类的名称可以在安装包中的 AndroidManifest.xml 文件获取。

如果要打开的 App 没有事先在手机上安装,我们可以直接指定 App 参数为安装包所在路径,这样程序启动时就会自动向手机安装并启动 App,如下所示:

from appium import webdriver


server = 'http://localhost:4723/wd/hub'

desired_caps = {

   'platformName': 'Android',

   'deviceName': 'MI_NOTE_Pro',

   'app': './weixin.apk'

}

driver = webdriver.Remote(server, desired_caps)

程序启动的时候就会寻找 PC 当前路径下的 APK 安装包,然后将其安装到手机中并启动。

查找元素

我们可以使用 Selenium 中通用的查找方法来实现元素的查找,如下所示:

el = driver.find_element_by_id('com.tencent.mm:id/cjk')

在 Selenium 中,其他查找元素的方法同样适用,在此不再赘述。

在 Android 平台上,我们还可以使用 UIAutomator 来进行元素选择,如下所示:

el = self.driver.find_element_by_android_uiautomator('new UiSelector().description("Animation")')

els = self.driver.find_elements_by_android_uiautomator('new UiSelector().clickable(true)')

在 iOS 平台上,我们可以使用 UIAutomation 来进行元素选择,如下所示:

el = self.driver.find_element_by_ios_uiautomation('.elements()[0]')

els = self.driver.find_elements_by_ios_uiautomation('.elements()')

还可以使用 iOS Predicates 来进行元素选择,如下所示:

el = self.driver.find_element_by_ios_predicate('wdName == "Buttons"')

els = self.driver.find_elements_by_ios_predicate('wdValue == "SearchBar" AND isWDDivisible == 1')

也可以使用 iOS Class Chain 来进行选择,如下所示:

el = self.driver.find_element_by_ios_class_chain('XCUIElementTypeWindow/XCUIElementTypeButton[3]')

els = self.driver.find_elements_by_ios_class_chain('XCUIElementTypeWindow/XCUIElementTypeButton')

但是此种方法只适用于 XCUITest 驱动,具体可以参考:https://github.com/appium/appium-xcuitest- driver。

点击

点击可以使用 tap() 方法,该方法可以模拟手指点击(最多五个手指),可设置按时长短(毫秒),代码如下所示:

tap(self, positions, duration=None)

参数:

  • positions,点击的位置组成的列表。
  • duration,点击持续时间。

实例如下:

driver.tap([(100, 20), (100, 60), (100, 100)], 500)

这样就可以模拟点击屏幕的某几个点。

另外对于某个元素如按钮来说,我们可以直接调用 cilck() 方法实现模拟点击,实例如下所示:

button = find_element_by_id('com.tencent.mm:id/btn')

button.click()

这样获取元素之后,然后调用 click() 方法即可实现该元素的模拟点击。

屏幕拖动

可以使用 scroll() 方法模拟屏幕滚动,用法如下所示:

scroll(self, origin_el, destination_el)

可以实现从元素 origin_el 滚动至元素 destination_el。

参数:

  • original_el,被操作的元素
  • destination_el,目标元素

实例如下:

driver.scroll(el1,el2)

我们还可以使用 swipe() 模拟从 A 点滑动到 B 点,用法如下:

swipe(self, start_x, start_y, end_x, end_y, duration=None)

参数:

  • start_x,开始位置的横坐标
  • start_y,开始位置的纵坐标
  • end_x,终止位置的横坐标
  • end_y,终止位置的纵坐标
  • duration,持续时间,毫秒

实例如下:

driver.swipe(100, 100, 100, 400, 5000)

这样可以实现在 5s 由 (100, 100) 滑动到 (100, 400)。

另外可以使用 flick() 方法模拟从 A 点快速滑动到 B 点,用法如下:

flick(self, start_x, start_y, end_x, end_y)

参数:

  • start_x,开始位置的横坐标
  • start_y,开始位置的纵坐标
  • end_x,终止位置的横坐标
  • end_y,终止位置的纵坐标

实例如下:

driver.flick(100, 100, 100, 400)

拖拽

可以使用 drag_and_drop() 实现某个元素拖动到另一个目标元素上。

用法如下:

drag_and_drop(self, origin_el, destination_el)

可以实现元素 origin_el 拖拽至元素 destination_el。

参数:

  • original_el,被拖拽的元素
  • destination_el,目标元素

实例如下所示:

driver.drag_and_drop(el1, el2)

文本输入

可以使用 set_text() 方法实现文本输入,如下所示:

el = find_element_by_id('com.tencent.mm:id/cjk')

el.set_text('Hello')

我们选中一个文本框元素之后,然后调用 set_text() 方法即可实现文本输入。

动作链

与 Selenium 中的 ActionChains 类似,Appium 中的 TouchAction 可支持的方法有 tap()、press()、long_press()、release()、move_to()、wait()、cancel() 等,实例如下所示:

el = self.driver.find_element_by_accessibility_id('Animation')

action = TouchAction(self.driver)

action.tap(el).perform()

首先选中一个元素,然后利用 TouchAction 实现点击操作。

如果想要实现拖动操作,可以用如下方式:

els = self.driver.find_elements_by_class_name('listView')

a1 = TouchAction()

a1.press(els[0]).move_to(x=10, y=0).move_to(x=10, y=-75).move_to(x=10, y=-600).release()

a2 = TouchAction()

a2.press(els[1]).move_to(x=10, y=10).move_to(x=10, y=-300).move_to(x=10, y=-600).release()

利用以上 API,我们就可以完成绝大部分操作。更多的 API 操作可以参考 Appium Python API 中文版 By-HZJ · TesterHome

5. 结语

本节中,我们主要了解了 Appium 的操作 App 的基本用法,以及常用 API 的用法。在下一节我们会用一个实例来演示 Appium 的使用方法。

相关文章
|
1月前
|
数据采集 存储 XML
Python爬虫:深入探索1688关键词接口获取之道
在数字化经济中,数据尤其在电商领域的价值日益凸显。1688作为中国领先的B2B平台,其关键词接口对商家至关重要。本文介绍如何通过Python爬虫技术,合法合规地获取1688关键词接口,助力商家洞察市场趋势,优化营销策略。
|
2天前
|
数据采集 供应链 API
Python爬虫与1688图片搜索API接口:深度解析与显著收益
在电子商务领域,数据是驱动业务决策的核心。阿里巴巴旗下的1688平台作为全球领先的B2B市场,提供了丰富的API接口,特别是图片搜索API(`item_search_img`),允许开发者通过上传图片搜索相似商品。本文介绍如何结合Python爬虫技术高效利用该接口,提升搜索效率和用户体验,助力企业实现自动化商品搜索、库存管理优化、竞品监控与定价策略调整等,显著提高运营效率和市场竞争力。
20 3
|
13天前
|
数据采集 存储 缓存
如何使用缓存技术提升Python爬虫效率
如何使用缓存技术提升Python爬虫效率
|
14天前
|
数据采集 Web App开发 监控
Python爬虫:爱奇艺榜单数据的实时监控
Python爬虫:爱奇艺榜单数据的实时监控
|
23天前
|
数据采集 JSON API
如何利用Python爬虫淘宝商品详情高级版(item_get_pro)API接口及返回值解析说明
本文介绍了如何利用Python爬虫技术调用淘宝商品详情高级版API接口(item_get_pro),获取商品的详细信息,包括标题、价格、销量等。文章涵盖了环境准备、API权限申请、请求构建和返回值解析等内容,强调了数据获取的合规性和安全性。
|
28天前
|
数据采集 存储 API
利用Python爬虫获取1688关键词接口全攻略
本文介绍如何使用Python爬虫技术合法合规地获取1688关键词接口数据,包括环境准备、注册1688开发者账号、获取Access Token、构建请求URL、发送API请求、解析HTML及数据处理存储等步骤,强调遵守法律法规和合理使用爬虫技术的重要性。
|
1月前
|
数据采集 JSON 开发者
Python爬虫京东商品详情数据接口
京东商品详情数据接口(JD.item_get)提供商品标题、价格、品牌、规格、图片等详细信息,适用于电商数据分析、竞品分析等。开发者需先注册账号、创建应用并申请接口权限,使用时需遵循相关规则,注意数据更新频率和错误处理。示例代码展示了如何通过 Python 调用此接口并处理返回的 JSON 数据。
|
2月前
|
XML 数据采集 数据格式
Python 爬虫必备杀器,xpath 解析 HTML
【11月更文挑战第17天】XPath 是一种用于在 XML 和 HTML 文档中定位节点的语言,通过路径表达式选取节点或节点集。它不仅适用于 XML,也广泛应用于 HTML 解析。基本语法包括标签名、属性、层级关系等的选择,如 `//p` 选择所有段落标签,`//a[@href='example.com']` 选择特定链接。在 Python 中,常用 lxml 库结合 XPath 进行网页数据抓取,支持高效解析与复杂信息提取。高级技巧涵盖轴的使用和函数应用,如 `contains()` 用于模糊匹配。
|
2月前
|
数据采集 XML 存储
构建高效的Python网络爬虫:从入门到实践
本文旨在通过深入浅出的方式,引导读者从零开始构建一个高效的Python网络爬虫。我们将探索爬虫的基本原理、核心组件以及如何利用Python的强大库进行数据抓取和处理。文章不仅提供理论指导,还结合实战案例,让读者能够快速掌握爬虫技术,并应用于实际项目中。无论你是编程新手还是有一定基础的开发者,都能在这篇文章中找到有价值的内容。
|
2月前
|
数据采集 JavaScript 前端开发
Python爬虫能处理动态加载的内容吗?
Python爬虫可处理动态加载内容,主要方法包括:使用Selenium模拟浏览器行为;分析网络请求,直接请求API获取数据;利用Pyppeteer控制无头Chrome。这些方法各有优势,适用于不同场景。
下一篇
开通oss服务