使用Appium爬取淘宝App数据

发表于:2019-4-03 13:42

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:DebugWorld    来源:掘金

  0x01、介绍说明
  1、简介
  
  Appium是一个自动化测试开源工具。通过WebDriver协议驱动IOS、AndroidWindows Phone平台上的原生应用、混合应用和web应用。
   Appium是一个自动化测试开源工具。通过WebDriver协议驱动IOS、Android、Windows Phone平台上的原生应用、混合应用和web应用。
  2、支持多平台、多语言
  appium是跨平台的,可以用在OSX、Windows以及Linux系统上运行。
  appium选择了Client/Server的设计模式。只要client能够发送http请求给server,那么的话client用什么语言来实现都是可以的,这就是Appium及Selenium(WebDriver)如何做到支持多语言的原因。
  appium扩展了WebDriver的协议,没有自己重新去实现一套。这样的好处是以前的WebDriver API能够直接被继承过来,以前的Selenium(WebDriver)各种语言的binding都可以拿来就用,省去了为每种语言开发一个client的工作量。
  3、Appium工作原理
  在安装和介绍appium之前,非常有必要介绍一下appium是如何工作的。
  通过上面一张图简单展示了appium的工具原理。
  首先,appium支持多语言,因为它针对流的几种语言分别开发的相应的appium库。好处就是我们可以选择自己熟悉的语言编写appium脚本。
  其次,appium支持多平台,包括MAC和Windows。它针对这两大平台开发了appium-Server。
  最后,appium又同时支持Android 和 iOS两个操作系统。这就使得appium变得非常灵活。
  当我在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官方下载网站https://www.oracle.com/technetwork/cn/java/javase/downloads/index.html?spm=a2c4e.11153940.blogcont593549.10.4f164466N7mmUH
  安装:按照提示安装即可
  验证:
   # 在终端输入以下命令
  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/Home
  export CLASS_PATH=$JAVA_HOME/lib
  export 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_profile
  vim ~/.bash_profile
  # 输入自己的路径,保存并退出
  export ANDROID_HOME=/Users/xxxxxxx/Documents/Android/android-sdk-macosx
  export 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安装appium
  cnpm 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安装
  下载:官方下载地址https://www.python.org/,选择Python 3.6.4
  安装:按照步骤安装就行
  python2和python3共存
   # mac 输入python命令默认是python2.7,通过以下命令查看不同python版本所在的目录
  which python
  which python2
  which python3
  # 创建软链接,python2和python3共存
  # python2.7的软连接设置为python2
  ln -s /usr/bin/python2.7 /usr/bin/python2
  # 删除原有的python的软连接
  rm /usr/bin/python
  # 把python3的软连接设置为python
  ln -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 successfully
  xxxxxxxunauthorized
  2、无线连接
  在USB连接下,输入 adb tcpip 5555
   # 端口号是任意的,只要不被占用就行
  adb tcpip 5555
  # 命令反馈信息
  restarting in TCP mode port: 5555
  查看手机设备局域网ip
# 查看手机设备的局域网ip
  adb shell ip -f inet addr show wlan0
  # 命令反馈信息,其中192.168.1.5就是内网ip,或者在手机端的wifi设置查看
  * 22: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> 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需要改为你手机设置的ip
  adb 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 attached
  192.168.1.5:5555device
  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-Client
  pip install selenium
  定位元素
  # 打开终端输入UIAutomatorviewer,就可以查看定位元素了
  UIAutomatorviewer
  
   爬取淘宝app
    import time
  from appium import webdriver
  from appium.webdriver.common import mobileby
  from appium.webdriver.webdriver import WebDriver
  from selenium.webdriver.support.wait import WebDriverWait
  from selenium.webdriver.support import expected_conditions as EC
  desired_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
  
     上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号