一、什么是AirtestProject? 根据官方介绍, AirtestProject是由网易游戏推出的一款自动化测试框架,包括:
Airtest:
是一个跨平台的、基于图像识别的UI自动化测试框架,适用于游戏和App,支持平台有Windows、Android和iOS。
Poco:
是一款基于UI控件识别的自动化测试框架,目前支持Unity3D/cocos2dx-*/Android原生app/iOS原生app/微信小程序,也可以在其他引擎中自行接入poco-sdk来使用。
AirtestIDE:
跨平台的UI自动化测试编辑器,内置了Airtest和Poco的相关插件功能,能够使用它快速简单地编写
Airtest
和Poco
代码。AirLab:
真机自动化云测试平台,目前提供了TOP100手机兼容性测试、海外云真机兼容性测试等服务。
私有化手机集群技术方案:
从硬件到软件,提供了企业内部私有化手机集群的解决方案。
看上去很复杂的样子。。。
二、爬虫需要用到什么?
AirtestIDE 编辑器
Airtest,截图即代码
Poco,UI即代码
手机 / Android 模拟器(本文使用雷电模拟器)
基础的 python 知识
耐心
三、一个爬虫demo
需求:
模拟人类操作,并爬取新浪新闻某关键词的最新 n 条新闻标题准备工作:
-
雷电模拟器(或手机)下载安装新浪新闻app;
AirtestIDE 连接模拟器(或手机);
大概操作如图:
连接成功后:
录制脚本
-
- 打开 app,初始化 poco:
结合 airtest 和 poco 进行点击、滑屏、输入等操作,完成搜索关键词 “高考” 输入:
# -*- encoding=utf8 -*-__author__ = "riku"from airtest.core.api import *from poco.drivers.android.uiautomation import AndroidUiautomationPocopoco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)auto_setup(__file__,devices=["Android://127.0.0.1:5037/emulator-5554"])clear_app("com.sina.news")start_app("com.sina.news")sleep(1.0)#同意服务条款wait(Template(r"tpl1596187774347.png", record_pos=(0.2, 0.433), resolution=(720, 1280)))touch(Template(r"tpl1596187793810.png", record_pos=(0.204, 0.44), resolution=(720, 1280)))# poco("com.sina.news:id/dn").wait_for_appearance()# poco("com.sina.news:id/dn").click()#等待主界面出现wait(Template(r"tpl1596177073198.png", record_pos=(0.244, 0.821), resolution=(720, 1280)))log("以下步骤完成搜索操作")#下滑以显示搜索框poco.swipe([0.5,0.5],[0.5,0.6],duration=0.3)sleep(1.0)#点击搜索poco("com.sina.news:id/aof").click()sleep(1.0)# 输入搜索内容poco("com.sina.news:id/adt").click()query = "高考"poco("com.sina.news:id/adt").set_text(query)#确认搜索poco("com.sina.news:id/adw").click()sleep(1.0)
效果:(注:上面 code 采用 airtest 的图像识别技术,下效果图采用 poco 的 UI 解析。效果相同)
code中的 airtest 方案图像识别如下:
爬取目标分析:
本demo是为了获取最新的新闻,因此仅记录s_feed_1和s_feed_2两部分内容。
以下代码对 s_fe ed_1 和 s_feed_2 进行遍历。出于演示目的,demo仅爬取最新 50 条新闻:创建 list 用于存储新闻标题;
首先遍历 s_feed_1。由于 sina 的 UI 设计中,在前面的 s_feed_1 所含新闻很少,而s_feed_2 很多。因此遍历时检查是否已完成 s_feed_1,并使用 poco.swipe 下滑屏幕(跳过推荐的视频、微博等),直到界面出现 s_feed_2;
每次添加 list 时检查是否包含重复内容,因为通常屏幕滑动仅滑动半屏左右,滑动后界面含有重复内容;
当 list 长度达到目标值(50)后,停止爬虫,并保存结果。
log("以下步骤完成存储操作")#新闻列表news = []# 此处仅记录前50条新闻total_count = 50cur_count = 0poco("s_feed_1").wait_for_appearance()while True: # s_feed_1 if poco("s_feed_1").exists(): for t in poco("s_feed_1").child(): if not t.exists(): continue # get_name获取标题 title = t.get_name() if not title in news: print(title) news.append(title) cur_count += 1 poco.swipe([0.5,0.7],[0.5,0.1],duration=0.5) sleep(1.0) # s_feed_2 elif not poco("s_feed_2").exists(): poco.swipe([0.5,0.7],[0.5,0.1],duration=0.2) else: for t in poco("s_feed_2").child("android.view.View").offspring(): if not t.exists(): continue # get_name获取标题 title = t.get_name() if not title in news: print(title) news.append(title) cur_count += 1 poco.swipe([0.5,0.7],[0.5,0.1],duration=0.5) sleep(1.0) if cur_count >= total_count: with open("sina_"+ query +".txt","w") as f: for i in news: f.write(i + "\n") break
最终效果
结果文件:sina_高考.txt
四、结语经过简单的 demo 可以看出,该框架操作简单,使用方便,是Android 爬虫的一大利器。感兴趣的童鞋可以直奔官网学习了(直接某度搜索 AirtestIDE 即可)。
【demo中某些细节详见官方教程】