博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Appium爬取淘宝App数据
阅读量:7188 次
发布时间:2019-06-29

本文共 8937 字,大约阅读时间需要 29 分钟。

0x01、介绍说明

1、简介

是一个自动化测试开源工具。通过WebDriver协议驱动IOS、Android、Windows Phone平台上的原生应用、混合应用和web应用。

2、Appium工作原理

Appium选择了Client/Server的设计模式,Server可以在OSX、Windows以及Linux系统上运行,Client支持Ruby、Python、Java、PHP、C#、JavaScript等语言的实现。

当我在MAC平台上,通过Python(python-client )编写了一个appium自动化脚本并执行,请求会首先到 appium.dum (MAC下的appium-Server),appium-Server通过解析,驱动iOS设备来执行appium自动化脚本。或者,我在Windows平台上,通过Java( java-client )编写了一个appium自动化脚本并执行,请求会首先到 appiumForWindow.zip(Window下的appium-Server),appium-Server通过解析,驱动Android虚拟机或真机来执行appium脚本。所以,你会看到appium的强大之处就在于此。

0x02、环境配置

本教程以MacBook Pro通过Python程序控制Android系统的淘宝App为例,因为Appium依赖Android SDK,Android SDK需要Java环境,所以所需环境如下:

  • Java
  • Android SDK
  • Appium
  • Python

1、 Java安装

  • 下载:
  • 安装:按照提示安装即可
  • 验证:
# 在终端输入以下命令java -version# 命令反馈信息,说明安装成功java version "1.8.0_202"Java(TM) SE Runtime Environment (build 1.8.0_202-b08)Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)复制代码
  • 配置环境:
# 打开.bash_profile文件vim ~/.bash_profile# 配置环境变量(路径需要更改为自己的Java安装路径),保存并退出export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Homeexport CLASS_PATH=$JAVA_HOME/libexport PATH=$PATH:$JAVA_HOME/bin# 配置生效source ~/.bash_profile复制代码

2、Android SDK 安装

  • 下载:
  • 解压:进入目录android-sdk-macoxs --> tool, 双击android文件来启动Android SDK Manager
  • Android SDK Manager:
    • SDK Path: 安装路径
    • 只需要安装Android SDK Tolls 、Android SDK Platform-tools和Android SDK Build-tools(默认会选中Android 9的模拟系统,如果下载了Android的模拟系统,只有无尽等待)
    • 点击 install

  • 配置环境
# 打开.bash_profilevim ~/.bash_profile# 输入自己的路径,保存并退出export ANDROID_HOME=/Users/xxxxxxx/Documents/Android/android-sdk-macosxexport PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools# 使配置生效vim ~/.bash_profile# 输入命令,查看是否成功adb --version# 出现-bash: adb: command not found错误,常见原因有两种# 1. 环境变量配置出错# 2. 重启电脑(至于为什么需要重启,母鸡啊)复制代码

3、Appium 安装

# 先安装brew, 如果已经安装过了请跳过/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"brew update# 再安装npm:brew install npm# 安装cnpm:淘宝NPM镜像npm install -g cnpm --registry=https://registry.npm.taobao.org# 用cnpm安装appiumcnpm install -g appium# 检测是否成功appium# 安装appium-doctor, 该软件能够检测appium正常运行所需要的环境是否都有npm install appium-doctor -g# 然后检测是环境配置好,如果出错重启电脑appium-doctor 复制代码
  • 根据appium-doctor反馈结果安装所需环境
# Xcode是控制ios的,暂时不用问# Carthage was NOT founf! 解决办法brew install carthage复制代码

4、Python3安装

  • 下载:,选择Python 3.6.4

  • 安装:按照步骤安装就行
  • python2和python3共存
# mac 输入python命令默认是python2.7,通过以下命令查看不同python版本所在的目录which pythonwhich python2which python3# 创建软链接,python2和python3共存# python2.7的软连接设置为python2ln -s /usr/bin/python2.7 /usr/bin/python2# 删除原有的python的软连接rm /usr/bin/python# 把python3的软连接设置为pythonln -s /usr/local/bin/python3 /usr/bin/python复制代码

0x03、建立连接

pc端和移动端的连接有两种方式USB连接和无线连接

1、 USB连接

  • 打开开发者模式和USB调试:允许USB安装、USB调试等权限
  • 打开pc终端
# 查看手机设备信息adb devices # 命令反馈信息,出现设备id号说明连接成功* daemon not running; starting now at tcp:5037* daemon started successfullyxxxxxxx	unauthorized复制代码

2、无线连接

  • 在USB连接下,输入 adb tcpip 5555
# 端口号是任意的,只要不被占用就行adb tcpip 5555# 命令反馈信息restarting in TCP mode port: 5555复制代码
  • 查看手机设备局域网ip
# 查看手机设备的局域网ipadb shell ip -f inet addr show wlan0 # 命令反馈信息,其中192.168.1.5就是内网ip,或者在手机端的wifi设置查看* 22: wlan0: 
mtu 1500 qdisc mq state UP qlen 1000    inet 192.168.1.5/24 brd 192.168.1.255 scope global wlan0       valid_lft forever preferred_lft forever复制代码
  • 无线连接
# ip需要改为你手机设置的ipadb connect 192.168.1.5# 命令反馈信息,说明连接成功,就可以不需要USB数据线连接了,但是pc端和移动端需要在同一个局域网下connected to 192.168.1.5:5555复制代码
  • 验证
# 断掉USB连接,输入以下命令adb devices# 命令反馈信息,此时手机的设备号就变成192.168.1.5:5555了List of devices attached192.168.1.5:5555	device复制代码

3、 SDK 命令

adb kill-server          # 断开连接adb install path_to_apk  # 通过命令安装app复制代码

0x04、控制程序

1、运行appium

# 启动命令。4444 端口号(可以随意设置,官方建议>=4444)、192.168.1.5:5555:获取到的手机设备号,在python程序里会用到。当程序python运行之后,该命令会打印操作日志appium -a 127.0.0.1 -p 4444 -U 192.168.1.5:5555复制代码

2、程序

  • 所需python库
pip install Appium-Python-Clientpip install selenium复制代码
  • 定位元素
# 打开终端输入UIAutomatorviewer,就可以查看定位元素了UIAutomatorviewer复制代码

  • 爬取淘宝app
import timefrom appium import webdriverfrom appium.webdriver.common import mobilebyfrom appium.webdriver.webdriver import WebDriverfrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECdesired_capabilities = {        'platformName': 'Android',                          # 系统        'deviceName': 'xxxxxxxx',                           # 移动设备号        'platformVersion': '6.0.1',                         # 系统版本        'appPackage': 'com.taobao.taobao',                  # 操作的app        'appActivity': 'com.taobao.tao.welcome.Welcome',    # 打开淘宝app首页        'unicodeKeyboard': True,        'resetKeyboard': True,        'dontStopAppOnReset': True,        'autoGrantPermissions': True,        'noReset': True,        'automationName': 'uiautomator2',        'newCommandTimeout': '36000',                       # 超时时间        'systemPort': '8202',                               # 端口号,操作不用设备使用不同端口号        'udid': 'xxxxxxxx',                                 # 移动设备号        'command_executor': 'http://127.0.0.1:4444/wd/hub'  # 和启动命令保持一致}class AppiumDemo(object):    def __init__(self):        self.driver = webdriver.Remote(command_executor=desired_capabilities['command_executor'],                                       desired_capabilities=desired_capabilities)        self.by = mobileby.MobileBy()        # 点击搜索框        self.wait_find_element(by_type=self.by.ID, value='com.taobao.taobao:id/home_searchedit').click()        # 点击店铺搜索        self.wait_find_element(by_type=self.by.XPATH, value='//android.widget.TextView[@text="店铺"]').click()    def wait_find_element(self, by_type: str, value: str, driver: WebDriver = None):        """        获取单个元素, 显式等待        :param driver: 驱动对象        :param by_type: 查找元素的操作        :param value: 查找元素的方法        :return:        """        driver = driver or self.driver        if not driver:            return driver        try:            WebDriverWait(driver, 10).until(EC.visibility_of_element_located(locator=(by_type, value)))            return driver.find_element(by_type, value)        except:            # self.logger.warning(traceback.format_exc())            return False    def wait_find_elements(self, by_type: str, value: str, driver: WebDriver = None):        """        获取多个元素, 显式等待        :param driver:        :param by_type:        :param value:        :return:        """        driver = driver or self.driver        if not driver:            return driver        try:            WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located(locator=(by_type, value)))            return driver.find_elements(by_type, value)        except:            return False    def get_size(self, driver: WebDriver = None):        """        获取屏幕大小        :param driver:        :return:        """        driver = driver or self.driver        if not driver:            return driver        x = driver.get_window_size()['width']        y = driver.get_window_size()['height']        return [x, y]    def swipe_up(self, driver: WebDriver = None, _time: int = 1000):        """        向上滑动        :param driver:        :param _time:        :return:        """        driver = driver or self.driver        if not driver:            return driver        try:            size = self.get_size(driver)            x1 = int(size[0] * 0.5)  # 起始x坐标            y1 = int(size[1] * 0.80)  # 起始y坐标            y2 = int(size[1] * 0.30)  # 终点y坐标            driver.swipe(x1, y1, x1, y2, _time)            return True        except:            return False    def execute(self, seed):        self.wait_find_element(by_type=self.by.ID, value='com.taobao.taobao:id/searchEdit').clear().send_keys(seed['keyword'])        self.wait_find_element(by_type=self.by.ID, value='com.taobao.taobao:id/searchbtn').click()        self.wait_find_element(by_type=self.by.XPATH, value='//android.widget.TextView[@text="销量优先"]').click()        shop_list = self.wait_find_elements(by_type=self.by.ID, value='com.taobao.taobao:id/shopTitle')        for shop_info in shop_list:            shop_info.click()            # 点击全部宝贝            self.wait_find_element(by_type=self.by.XPATH, value='//android.widget.FrameLayout'                                                                '[@content-desc="全部宝贝"]').click()            for i in range(3):                # 获取这一屏的数据                item_list = self.wait_find_elements(by_type=self.by.ID, value="com.taobao.taobao:id/title")                for item_info in item_list:                    print(item_info.text)                self.swipe_up()                 # 向上滑动                time.sleep(0.5)                 # 一定要延时            self.driver.back()                  # 返回上一级        self.driver.back()def main():    seed = {        'keyword': 'Python 书'    }    spider = AppiumDemo()    while True:        spider.execute(seed=seed)if __name__ == '__main__':    main()复制代码

程序第一次运行的时候,会在手机安装3个app,一定要同意安装,只有Appium Settings在桌面有图标

  • Appium Settings
  • io.appium.uiautomator2.server
  • io.appium.uiautomator2.server.test

0x05、参考

转载于:https://juejin.im/post/5c99a4ee518825079c3a7d34

你可能感兴趣的文章
elasticsearch简单JavaAPI总结
查看>>
线索化二叉树
查看>>
vimrc
查看>>
【Spark亚太研究院系列丛书】Spark实战高手之路-第一章 构建Spark集群(第四步)(1)...
查看>>
Perl语言之统计特定字符串个数
查看>>
Linux用户和组管理
查看>>
Eclipse中从svn上检出项目无法识别jar包
查看>>
shell实现FTP自动批量上传下载文件
查看>>
我的友情链接
查看>>
Mybatis使用存储过程以及原理
查看>>
【Objective-C】OC中字典基本概念和常用方法(NSDictionary和NSMutableDictionary)
查看>>
maven打包包含配置文件
查看>>
C# readonly与const比较
查看>>
我的友情链接
查看>>
我的大学n糊口
查看>>
设置easyUi弹出窗在弹出框(iframe)中不居中问题
查看>>
Scrapy框架下第一个爬虫
查看>>
自动化运维工具puppet(五)
查看>>
linux网络命令(八)之top、htop
查看>>
【Windows和Linux下定时删除某天前的文件的脚本】
查看>>