简介
本文将介绍如何使用Airtest自动化工具来模拟用户操作,从某云音乐中爬取与特定关键词相关的歌曲名称。我们将以搜索“文字”相关的歌曲为例,并将结果保存到本地文件。
准备工作
- 安装Airtest并配置好Android设备或模拟器。
- 确保你的设备上已安装某云音乐应用。
步骤详解
1. 导入必要的库
首先,我们需要导入Airtest核心API以及处理JSON数据的库。同时设置脚本作者信息。
# -*- encoding=utf8 -*-
__author__ = "20220"
from airtest.core.api import *
import json
auto_setup(__file__)
2. 启动某云音乐应用
通过start_app
函数启动某云音乐应用。
# 启动某云音乐应用
start_app("com.####.music")
3. 初始化Poco驱动
初始化用于UI自动化的Poco驱动,这里指定为Android UI自动化模式。
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
4. 执行搜索操作
执行一系列触控和输入操作以完成搜索功能。这包括点击搜索框、输入搜索词(此处为“文字”)、点击搜索按钮等。
# 点击搜索框
sleep(1.0)
touch(Template(r"tpl1729174879203.png", record_pos=(-0.305, -0.946), resolution=(1080, 2340)))
# 输入搜索关键词“文字”
sleep(1.0)
text("文字", search=False)
# 点击搜索按钮
touch(Template(r"tpl1722922645319.png", record_pos=(0.416, -0.941), resolution=(1080, 2340)))
# 点击相关搜索结果
sleep(1.0)
touch(Template(r"tpl1729175412189.png", record_pos=(-0.07, 0.049), resolution=(1080, 2340)))
5. 获取并打印当前UI树
为了调试目的,可以打印出当前界面的UI元素结构。
ui_tree = poco.dump()
print(ui_tree)
6. 初始化变量
设置一些变量来跟踪已经抓取的歌曲数量以及迭代次数。
# 初始化变量
titles = []
current_count, last_count = 0, 0
i = 0
7. 循环抓取歌曲名称
使用一个无限循环来持续滚动页面并抓取新的歌曲名称,直到没有新数据加载为止。每次循环中,我们都会检查是否找到了新的歌曲,并且在找到新内容时更新列表。
第一次迭代:获取初始列表中的歌曲
while True:
# 记录上一次迭代时的歌曲数量
last_count = len(titles)
if i == 0: # 第一次迭代时获取第一个列表的歌曲
for title in poco("android.widget.LinearLayout").offspring("com.netease.cloudmusic:id/musicContainer").child("android.widget.FrameLayout").child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.view.ViewGroup")[2].child("android.view.ViewGroup")[1].child("android.view.ViewGroup").offspring("android.widget.FrameLayout").child("android.view.ViewGroup").child("android.view.ViewGroup")[1].child("android.view.ViewGroup"):
a = title.child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.view.ViewGroup")[1].child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.widget.TextView")[0]
name = a.get_text()
if name not in titles:
titles.append(name)
print(name) # 可选:打印歌曲名称
后续迭代:获取更多列表中的歌曲
else: # 其他迭代时获取其他列表的歌曲
sleep(1.0)
titles_container = poco("android.widget.LinearLayout").offspring("com.netease.cloudmusic:id/musicContainer").child("android.widget.FrameLayout").child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.view.ViewGroup")[2].child("android.view.ViewGroup")[1].child("android.view.ViewGroup").offspring("android.widget.FrameLayout")[1].child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.view.ViewGroup")
for title in titles_container:
a = title.child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.view.ViewGroup")[1].child("android.view.ViewGroup").child("android.view.ViewGroup").child("android.widget.TextView")[0]
name = a.get_text()
if name not in titles:
titles.append(name)
print(name) # 可选:打印歌曲名称
更新计数器与滑动操作
# 更新当前歌曲数量
current_count = len(titles)
# 模拟向上滑动以加载更多内容
poco.swipe([0.5, 0.7], [0.5, 0.1], duration=2)
sleep(1.0)
i += 1
# 如果没有新数据加载,退出循环
if current_count == last_count:
print(f"总共爬取 {last_count} 首歌曲的名称")
break
8. 将结果保存到文件
最后一步是将收集到的所有歌曲名称写入本地文本文件。
# 定义文件路径
file_path = r"E:\Python\安卓端自动化\day 01\song_titles.txt"
# 将歌曲名称写入文件
with open(file_path, "w", encoding="utf-8") as file:
for title in titles:
file.write(title + "\n")
print(f"歌曲名称已保存至 {file_path}")
结论
通过上述步骤,我们成功实现了对某云音乐应用内特定关键词相关歌曲的自动化爬取。这种方法可以应用于类似的场景,帮助你快速获取所需信息而不必手动执行重复的操作。在使用Airtest或其他类似工具进行自动化测试或数据抓取时,始终要遵循合法合规的原则。
这包括但不限于:
尊重网站规则:确保你的行为符合目标网站的服务条款(Terms of Service, ToS)。
遵守法律法规:了解并遵守你所在地区关于网络数据获取的相关法律规定。
道德考量:避免任何可能侵犯他人隐私权、版权的行为。
免责声明:
本文档所提供的信息仅供教育和个人学习参考之用。
作者不对因按照本指南所采取行动导致的任何直接或间接损失承担责任。
在尝试文中提到的技术之前,请自行确认其合法性,并保证您的活动不违反当地法律及被访问网站的具体规定。
使用自动化工具时请保持良好职业道德,切勿滥用技术损害他人权益。
使用Airtest自动化某易云音乐爬取歌曲名称