语言:python
1.环境搭建
1.1安装Python
安装完毕后确保环境变量配置完毕
1.2安装atx-agent用于连接手机
在安装atx和weditor建立连接的同时需要先下载安卓调试桥adb
将adb所在目录设置Path环境变量
用数据线连接电脑然后开启开发者模式并在cmd输入adb devices列出连接的设备
将获取的设备序列号输入在浏览器Weditor中并connect,开始自动安装ATX到该手机上
1.3安装weditor用于查看手机
pip install weditor==0.6.4
pip list | findstr weditor
python -m weditor
如果安装失败可以尝试如下方式解决:
- pip install -U setuptools //更新模块setuptools
- pip install -U weditor
- git clone https://github.com/openatx/weditor
- pip3 install -e weditor
1.4安装uiautomator2用于代码操作手机
编写代码
也可在工具的插件市场中安装
device = u2.connect("192.168.0.187") # tcpip同个局域网连接,的方式即可连接手机设备通过adb桥的tcp协议进行无线联调
import uiautomator2 as u2; # 依赖包
if __name__ == '__main__':
# device = u2.connect() # 模拟器默认连接方式
device = u2.connect("192.168.0.187:5555") # tcpip同个局域网连接
# device = u2.connect("46d0c494") # usb连接,需要开启开发者模式,用atx也可以开启开发中模式,cmd输入adb devices获取设备号
print("device_info==========================")
print(device.device_info)
device(text='QQ').click()
无线联机
手机开启开发者模式并开启usb调试,此时才能连接同局域网目标手机的tcp/ip端口。连接后才能通信。更多原理详见安卓官网
2.API介绍
2.1app的安装、卸载、打开、关闭、清除数据
获取包名的三种方式:
获取包名时,该app必须运行起来
2.2设备信息、屏幕大小、截屏、推送文件到手机、拉取手机的文件
案例演练
查看手机的文件系统
2.3按键操作
音量加、减、静音、预览最近打开的程序、电源键
2.4元素定位
遇见相同的元素,这里选择点击第三个
2.5元素定位
层级定位
找子元素
找同级元素
找父级元素(父级很慢建议不要用)
相对定位
这种方式速度较慢
2.6事件操作
点击
滑动
输入
2.7等待
2.8获取提示语
3.报错大全
3.1adb无法使用,提示error: unknown host service的解决办法
uiautomator2是python语言实现的一个app自动化测试框架,weditor是python版的uiautomator2中的一个元素定位工具。
下面是我在使用weditor中遇到的一个报错,自己给自己挖的坑,含泪也要踩完。。。
1、首先通过adb devices命令能够识别到至少一个android设备【我这里使用的是雷电模拟器v4.0.22】,
2、确保设备当前没有被任何其它的应用程序所占用,占用的话需要关闭其他应用,
3、继续在cmd里输入weditor,稍等片刻会打开一个浏览器,如图
4、竟然报错了 adbutils.errors.AdbError:unknown host service
解决方法一
看报错是adb的问题,但是不知道怎么下手,多次尝试重启电脑、更新adb都没有解决,后来经一位大佬提醒,在cmd里面 "where adb"看看有几个adb,如图:
瞬间恍然大悟,原来是之前给自己挖了一个大坑,两个地方都有adb,于是果断删除第一个adb,重新走了一遍流程,终于成功了
解决方法二
使用adb时需要5037端口是空闲的,此时只需要辨别电脑的5037端口被哪个应用程序占用即可。
1. 打开命令行,输入命令:netstat -ano |findstr "5037"
2、查看到对应的进程的PID是7952
Ctrl+alt+delete,打开任务管理器,查看是哪个进程占用了7952
这里是sjk_daemon.exe(百度到是金山手机助手)占用了此进程,需要将该进程
3、结束该进程
4、如果发现一个进程,多次关闭无法关闭,可以尝试卸载该应用最后,如果还是无法连接设备,提示devices notfound,可以尝试如下命令:
adb kill-server
adb start-server
adb remount
4.selenum爬虫
今天在官网看了下Selenium库,总结了下常用的方法,直接上代码。(沈略环境搭建,网上多得是),新手建议去了解10分钟再来看这里的代码。
这里列举一下常用的查找元素方法:其实find_element_by_xpath是万能的。
单元素定位
find_element_by_name
find_element_by_id
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
find_element(By.ID,"kw")
find_element(By.NAME,"wd")
find_element(By.CLASS_NAME,"s_ipt")
find_element(By.TAG_NAME,"input")
find_element(By.LINK_TEXT,u"新闻")
find_element(By.PARTIAL_LINK_TEXT,u"新")
find_element(By.XPATH,"//*[@class='bg s_btn']")
find_element(By.CSS_SELECTOR,"span.bg s_btn_wr>input#su")
多元素定位
find_elements_by_name
find_elements_by_id
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
返回的是list列表,用print(type(elements_name))即可看到它的类型是list。
from selenium import webdriver
import lxml.html
from selenium.webdriver.common.by import By
import time
from selenium.webdriver import ActionChains
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
browser = webdriver.Chrome()
# 先梳理一下逻辑,在讲下xpath的使用,最后讲下常用方法。
'''
1、导入webdriver模块
2、通过该模块点出一个浏览器对象
3、通过浏览器对象点出连接——browser.get("")
5、通过浏览器对象点出当前页面的html标签内容——browser.page_source
6、通过浏览器对象点出要获取元素的方法来获取html标签——browser.find_element(By.ID,"q").click() or browser.find_element_by_id("q").click()
7、这里重点讲一下xpath的使用,因为其他的都简单,
import lxml.html
html1 = "html内容"
selector = lxml.html.fromstring(html1)
(1)、没有属性的标签可省略,属性都相同的标签可省略。
(2)、属性以某字符串开头:xpath('//div[starts-with(@id,"test")]/text()')遍历即可。
(3)、属性值包含相同字符串:把上面的starts-with改为contains遍历即可。
(4)、获取子标签下的文字:lists_index=selector.xpath('//div[@class="useful"]')。info_list=lists_index[0].xpath('ul/li/text()')输出即可。
(5)、获取不同标签下的文字:data=selector.xpath('//div[@id="test3"]')[0]。info=data.xpath('string(.)')输出即可。
(6)、第四句的意思是,获取class为useful的div标签,以列表形式返回,第一个div为div[0],以此类推;后面那句也是以列表的形式返回文本数据。
第五句的意思是,获取id为test3的div标签的第一个div;后面那句是返回这个div[0]标签下的所有文本内容。
'''
html1 = '''
<html>
<head>
<title>ceshi</title>
</head>
<body>
<div class="useful">
<ul>
<li class="info">1</li>
<li class="info">2</li>
<li class="info">3</li>
<li class="inf">4</li>
</ul>
</div>
<div class = "useful">
<ul>
<li class="info">5</li>
<li class="info">6</li>
</ul>
</div>
</body>
</html>
'''
selector = lxml.html.fromstring(html1)
useful = selector.xpath('//div[@class="useful"]')
info_list = useful[0].xpath('ul/li/text()')
print(info_list)
# 打开知乎,滑到最底下,输出一句话
# browser.get("http://www.zhihu.com/explore")
# browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
# browser.execute_script('alert("To Bottom")')
# 打开淘宝,输入ipad,删除后输入MakBook pro,点击搜索
# browser.get("http://www.taobao.com")
# input_str = browser.find_element_by_id('q')
# input_str.send_keys("ipad")
# time.sleep(1)
# input_str.clear()
# input_str.send_keys("MakBook pro")
# button = browser.find_element_by_class_name('btn-search')
# button.click()
# 打开一个网址,拖动滑块到吻合的地方
# url = "http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"
# browser.get(url)
# browser.switch_to.frame('iframeResult')
# source = browser.find_element_by_css_selector('#draggable')
# target = browser.find_element_by_css_selector('#droppable')
# actions = ActionChains(browser)
# actions.drag_and_drop(source, target)
# actions.perform()
# 打开网页,获取元素touple,获取属性的值
# url = 'https://www.zhihu.com/explore'
# browser.get(url)
# logo = browser.find_element_by_id('zh-top-link-logo')
# print(logo)
# print(logo.get_attribute('class'))
# 获取ID,位置,标签名
# url = 'https://www.zhihu.com/explore'
# browser.get(url)
# input = browser.find_element_by_class_name('zu-top-add-question')
# print(input.id)
# print(input.location)
# print(input.tag_name)
# print(input.size)
# 切入到frame中以及切出来
# url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
# browser.get(url)
# browser.switch_to.frame('iframeResult') # 切入
# source = browser.find_element_by_css_selector('#draggable')
# print(source)
# try:
# logo = browser.find_element_by_class_name('logo')
# except NoSuchElementException:
# print('NO LOGO')
#
# browser.switch_to.parent_frame() # 切出
# logo = browser.find_element_by_class_name('logo')
# print(logo)
# print(logo.text)
# 隐式等待(等10秒钟后还没出现就报错)
# browser.implicitly_wait(10)
# browser.get('https://www.zhihu.com/explore')
# input = browser.find_element_by_class_name('zu-top-add-question')
# print(input)
# 显示等待(等待某个元素出现)
# browser.get('https://www.taobao.com/')
# wait = WebDriverWait(browser, 10)
# input = wait.until(EC.presence_of_element_located((By.ID, 'q'))) # 元素是否出现
# button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search'))) # 元素是否可点击
# print(input, button)
'''
常用的判断条件:
title_is 标题是某内容
title_contains 标题包含某内容
presence_of_element_located 元素加载出,传入定位元组,如(By.ID, 'p')
visibility_of_element_located 元素可见,传入定位元组
visibility_of 可见,传入元素对象
presence_of_all_elements_located 所有元素加载出
text_to_be_present_in_element 某个元素文本包含某文字
text_to_be_present_in_element_value 某个元素值包含某文字
frame_to_be_available_and_switch_to_it frame加载并切换
invisibility_of_element_located 元素不可见
element_to_be_clickable 元素可点击
staleness_of 判断一个元素是否仍在DOM,可判断页面是否已经刷新
element_to_be_selected 元素可选择,传元素对象
element_located_to_be_selected 元素可选择,传入定位元组
element_selection_state_to_be 传入元素对象以及状态,相等返回True,否则返回False
element_located_selection_state_to_be 传入定位元组以及状态,相等返回True,否则返回False
alert_is_present 是否出现Alert
'''
# 浏览器的前进和后退
# browser = webdriver.Chrome()
# browser.get('https://www.baidu.com/')
# browser.get('https://www.taobao.com/')
# browser.get('https://www.zhihu.com/explore')
# browser.back()
# time.sleep(1)
# browser.forward()
# browser.close()
# cookie操作
# browser.get('https://www.zhihu.com/explore')
# print(browser.get_cookies()) # 得到
# browser.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'zhaofan'}) # 添加
# print(browser.get_cookies())
# browser.delete_all_cookies() # 删除
# print(browser.get_cookies())
# 选项卡的切换
# browser.get('https://www.baidu.com') # 去百度(卡一)
# browser.execute_script('window.open()') # 打开新选项卡(卡二)
# print(browser.window_handles)
# browser.switch_to_window(browser.window_handles[1]) # 获得卡二 去淘宝
# browser.get('https://www.taobao.com')
# time.sleep(1)
# browser.switch_to_window(browser.window_handles[0]) # 获得卡一 去知乎
# browser.get('https://www.zhihu.com/explore')
# 异常处理
# 这里的异常比较复杂,官网的参考地址:
# http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions
# 超时、没找到元素异常处理
# try:
# browser.get('https://www.baidu.com')
# except TimeoutException:
# print('Time Out')
# try:
# browser.find_element_by_id('hello')
# except NoSuchElementException:
# print('No Element')
# finally:
# browser.close()