当前位置: 首页 > news >正文

Airtest-Selenium实操小课②:刷B站视频

1. 前言

上一课我们讲到用Airtest-Selenium爬取网站上我们需要的信息数据,还没看的同学可以戳这里看看~

那么今天的推文,我们就来说说看,怎么实现看b站、刷b站的日常操作,包括点击暂停,发弹幕,点赞,收藏等操作,仅供大家参考学习~

2.需求分析和准备

整体的需求大致可以分为以下步骤:

  • 打开chrome浏览器
  • 打开百度网页
  • 搜索“哔哩哔哩”
  • 点击进入“哔哩哔哩”官网
  • 搜索关键词“Airtest酱”
  • 点击进入“Airtest酱”首页,随机点击播放视频
  • 并对视频点击暂停,发弹幕,点赞,收藏

在写脚本之前,我们需要准备好社区版AirtestIDE(目前最新版为1.2.16),设置好chrome.exe地址和对应的driver;并且确保我们的chrome浏览器版本不是太高以及selenium是4.0以下即可(这些兼容问题我们都会在后续的版本修复)。

3. 脚本实现与运行效果

3.1 脚本运行效果

我们在编写这次代码的时候,我们主要是使用了页面元素定位的方式去进行操作交互的,除此之外还实现了保存cookie、读取cookie的一个操作。大家在日常使用也会发现,在首次通过脚本开启的chrome网页界面是无cookie的,那么我们在进行一些任务之前是需要先登录后才能进行下一步操作的,可以通过首次登录时读取cookie数据保存到本地,往后每次运行只需要读取本地的cookie文件就可以轻松登录啦~

先来看下我们整体的运行效果:

Airtest-selenium实现自动化刷b站

3.2 完整代码分享

这里也附上完整的示例代码给大家参考,有需要的同学可以自取学习哦:

# -*- encoding=utf8 -*-
from airtest.core.api import *
# 引入selenium的webdriver模块
from airtest_selenium.proxy import WebChrome
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import threading
import time
import random
import json#保存以及调用cookie的线程
class UtilFunc():def cookie_is_exist_(self, cook_name='_'):      # 检查txt文件是否存在if os.path.exists(f'{cook_name}cookies.txt'):return Truereturn Falsedef cookie_save_(self, driver, cook_name='_'):     #保存cookie到txt文件中以便下次读取# 获取当前页面的所有cookiecookies = driver.get_cookies()# 将cookie转换为JSON字符串cookies_json = json.dumps(cookies)# 保存cookie到txt文件with open(f'{cook_name}cookies.txt', 'w') as file:file.write(cookies_json)print(f"保存cookies:{cookies}")def cookie_set_(self, driver, cook_name='_'):     #读取cookie文件并给当前网站设置已存cookie# 从txt文件读取JSON_cookie数据with open(f'{cook_name}cookies.txt', 'r', encoding='gbk') as file:json_data = file.read()# 将JSON数据转换为列表data_list = json.loads(json_data)for cookie in data_list:driver.add_cookie(cookie)print("设置cookie")# 创建一个实例,代码运行到这里,会打开一个chrome浏览器
driver = WebChrome()
isLogin = False   #存储登录状态值,False为未登录,True为已登录#打开chrome浏览器并打开视频播放
def start_selenium():driver.implicitly_wait(20)driver.get("https://www.baidu.com/")# 输入搜索关键词并提交搜索search_box = driver.find_element_by_name('wd')search_box.send_keys('哔哩哔哩')search_box.submit()try:# 查找搜索结果中文本为 "哔哩哔哩" 的元素并点击results = driver.find_elements_by_xpath('//div[@id="content_left"]//span[contains(text(), "哔哩哔哩")]')if results:results[0].click()print("点击了哔哩哔哩搜索结果")except Exception as e:element = driver.find_element_by_xpath("//div[@id='content_left']/div[@id='1']/div[@class='c-container']/div[1]/h3[@class='c-title t t tts-title']/a")element.click()driver.switch_to_new_tab()  # 切换界面util_cookie = UtilFunc()if util_cookie.cookie_is_exist_("Airtest酱登录"):  # 存在cookie文件,设置cookieutil_cookie.cookie_set_(driver, "Airtest酱登录")# 输入搜索关键词并提交搜索search_box = driver.find_element_by_class_name('nav-search-input')search_box.send_keys('Airtest酱')# 模拟发送Enter键search_box.send_keys(Keys.ENTER)sleep(5)driver.switch_to_new_tab()  # 切换界面results_ = driver.find_elements_by_xpath('//div[@class="bili-video-card__info--right"]//span[contains(text(),"Airtest酱")]')if results_:results_[0].click()driver.switch_to_new_tab()  # 切换界面driver.refresh()sleep(2)video_ele = driver.find_element_by_xpath("//div[@title='14天Airtest自动化测试小白课程']")# 滚动到指定元素处driver.execute_script("arguments[0].scrollIntoView(true);", video_ele)sleep(5)video_ele.click()driver.switch_to_new_tab()  # 切换界面# 获取所有视频video_list = driver.find_elements_by_xpath("//ul[@class='row video-list clearfix']//a[@class='title']")random_element = random.choice(video_list)random_element.click()  # 随机播放一个driver.switch_to_new_tab()  # 切换界面#登录
def is_login():"""线程检测登录弹窗"""def is_no_login(*args):global isLogin  # 在线程内修改外部常量的值no_login_tip = Truewhile True:element = driver.find_elements_by_css_selector('.bili-mini-content-wp')if len(element) > 0:if no_login_tip:print("未登录 请在五分钟内扫码")no_login_tip = Falseelse:print("未检测到登录弹窗")check_login_ele = driver.find_elements_by_css_selector('.bpx-player-dm-wrap')if not check_login_ele:isLogin = TrueUtilFunc().cookie_save_(driver, "Airtest酱登录")print("保存cookie")breaklog_text_array = [element.text for element in check_login_ele]  # 使用列表推导式简化代码if "请先登录或注册" in log_text_array:loginbtn = driver.find_elements_by_xpath("//div[@class='bili-header fixed-header']//div[@class='header-login-entry']")if loginbtn:loginbtn[0].click()isLogin = Falseprint("判断cookie文件是否存在,方便下次调用,设置后刷新页面")else:isLogin = TrueUtilFunc().cookie_save_(driver, "Airtest酱登录")print("保存cookie")breakthread = threading.Thread(target=is_no_login, args=("args",))thread.start()#暂停播放
def video_pause_and_play(check_btn=False):if isLogin:try:paus_btn = driver.find_elements_by_xpath("//*[@id=\"bilibili-player\"]//div[@class='bpx-player-ctrl-btn bpx-player-ctrl-play']")if paus_btn[0]:detection_time1 = driver.find_elements_by_xpath('//*[@class="bpx-player-control-bottom-left"]//div[@class="bpx-player-ctrl-time-label"]')start_time = detection_time1[0].textsleep(5)# 时间戳检测是否在播放detection_time2 = driver.find_elements_by_xpath('//*[@class="bpx-player-control-bottom-left"]//div[@class="bpx-player-ctrl-time-label"]')end_time = detection_time2[0].textif start_time == end_time or check_btn:print("点击播放(暂停)按钮")paus_btn[0].click()except Exception as e:print(f"点击播放(暂停)出错{e}")#发送弹幕
def video_sms(sms_body="不错"):if isLogin:try:sms_input_edit = driver.find_element_by_xpath("//input[@class='bpx-player-dm-input']")sms_input_edit.send_keys(sms_body)# 模拟发送Enter键sms_input_edit.send_keys(Keys.ENTER)except Exception as e:print(f"发弹幕出错{e}")print(f"发送弹幕:{sms_body}")#点赞
def video_love():if isLogin:print("点赞")try:sms_input_edit = driver.find_elements_by_xpath("//div[@class='toolbar-left-item-wrap']//div[@class='video-like video-toolbar-left-item']")if not sms_input_edit:print("已经点赞")returnsms_input_edit[0].click()except Exception as e:print(f"点赞出错{e}")#收藏
def video_collect():if isLogin:print("收藏")try:colle_btn = driver.find_elements_by_xpath("//div[@class='toolbar-left-item-wrap']//div[@class='video-fav video-toolbar-left-item']")if not colle_btn:print("已经收藏")returncolle_btn[0].click()sleep(2)list_coll = driver.find_elements_by_xpath("//div[@class='group-list']//ul/li/label")random_element = random.choice(list_coll)  # 随机收藏# 滚动到指定元素处driver.execute_script("arguments[0].scrollIntoView(true);", random_element)sleep(2)random_element.click()  # 随机收藏一个sleep(2)driver.find_element_by_xpath("//div/button[@class='btn submit-move']").click()  # 确认收藏except Exception as e:print(f"收藏出错{e}")# 等待元素出现
def wait_for_element(driver, selector, timeout=60 * 5):try:element = WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.XPATH, selector)))return elementexcept Exception:print("元素未出现")return None#头像元素初始化
selem = "//div[@class='bili-header fixed-header']//*[contains(@class, 'header-avatar-wrap--container mini-avatar--init')]"if __name__ == "__main__":start_selenium()  # 开启浏览器找到视频播放is_login()  # 检测是否出现登录弹窗# 等待元素出现element = wait_for_element(driver, selem)if element:print("检测到已经登录")# 暂停和播放视频for _ in range(2):video_pause_and_play()sleep(3)driver.refresh()# 发送弹幕sms_list = ["感觉不错,收藏了", "666,这么强", "自动化还得看airtest", "干货呀", "麦克阿瑟直呼内行"]for item in sms_list:wait_time = random.randint(5, 10)  # 随机生成等待时间,单位为秒time.sleep(wait_time)  # 等待随机的时间video_sms(item)  # 评论# 点赞和收藏视频for action in [video_love, video_collect]:action()sleep(3)else:print("登录超时")
3.2 重要知识点
1)切换新页面并打开新的标签页
driver.switch_to_new_tab()
**2)将随机的元素 random_element对象的“顶端”移动到与当前窗口的“顶部”**对齐。
driver.execute_script("arguments[0].scrollIntoView(true);", random_element)

3) 从非空序列中随机选取一个数据并返回,该序列可以是list、tuple、str、set**。**

random.choice()

4) 通过实例化threading.Thread类创建线程,target:在线程中调用的对象,可以为函数或者方法;args为target对象的参数。

start():开启线程,如果线程是通过继承threading.Thread子类的方法定义的,则调用该类中的run()方法;start()只能调用一次,否则报RuntimeError。

threading.Thread(target=is_no_login, args=("args",))
thread.start()

5) 使用expected_conditions模块(在使用时通常重命名为EC模块)去判断特定元素是否存在于页面DOM树中,如果是,则返回该元素(单个元素),否则就报错。

EC.presence_of_element_located((By.XPATH, selector))

4. 注意事项与小结

4.1 相关教程
  • 如何使用Airtest-selenium进行web端的页面元素交互
  • 如何设置chromedriver以及一些常见的web脚本问题
  • 为什么AirtestIDE无法检索web控件?
4.2 课程小结

在本周的课程中,我们介绍了如何使用Airtest-selenium进行自动化刷B站视频的操作流程,也分享了Airtest-selenium比较常见的用法。但是,请大家注意,我们的分享仅供学习参考哦!我们分享的代码并不是永远适用的,因为网页的页面元素可能会不断更新。

同时,我们也非常欢迎同学们能够提供自己常用场景的代码,我们会积极分享相关的使用技巧。让我们一起努力,共同进步~

相关文章:

Airtest-Selenium实操小课②:刷B站视频

1. 前言 上一课我们讲到用Airtest-Selenium爬取网站上我们需要的信息数据,还没看的同学可以戳这里看看~ 那么今天的推文,我们就来说说看,怎么实现看b站、刷b站的日常操作,包括点击暂停,发弹幕,点赞&#…...

Linux chmod命令详解

Linux chmod(英文全拼:change mode)命令是控制用户对文件的权限的命令 Linux/Unix 的文件调用权限分为三级 : 文件所有者(Owner)、用户组(Group)、其它用户(Other Users&#xff09…...

求幸存数之和 - 华为OD统一考试

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 给一个正整数列nums,一个跳数jump,及幸存数量left。运算过程为:从索引为0的位置开始向后跳,中间跳过 J 个数字,命中索引为 J+1 的数字,该数被敲出,并从该点起跳,以此类推,直到幸存left个数为止。…...

【QML COOK】- 008-自定义属性

前面介绍了用C定义QML类型,通常在使用Qt Quick开发项目时,C定义后端数据类型,前端则完全使用QML实现。而QML类型或Qt Quick中的类型时不免需要为对象增加一些属性,本篇就来介绍如何自定义属性。 1. 创建项目,并编辑Ma…...

前端页面优化做的工作

1.分析模块占用空间 new (require(webpack-bundle-analyzer).BundleAnalyzerPlugin)() 2.使用谷歌浏览器中的layers,看下有没有影响性能的模块,或者应该销毁没销毁的 3.由于我们页面中含有很大的序列帧动画,所以会导致页面性能低&#xff0…...

Spark六:Spark 底层执行原理SparkContext、DAG、TaskScheduler

Spark底层执行原理 学习Spark运行流程 学习链接:https://mp.weixin.qq.com/s/caCk3mM5iXy0FaXCLkDwYQ 一、Spark运行流程 流程: SparkContext向管理器注册并向资源管理器申请运行Executor资源管理器分配Executor,然后资源管理器启动Execut…...

关于鸿蒙的笔记整理

提示:有使用过 vue 或 react 的小伙伴更容易理解 知识点强调: ArkTS所有内容都不支持深层数据更新 UI渲染 文章目录 一、关于样式1 . 默认单位 vp2 . 写公共样式 二 、 加载图片三 、 自定义构建函数 Builder四、构建函数-BuilderParam 传递UI五 、 父子…...

【漏洞复现】先锋WEB燃气收费系统文件上传漏洞 1day

漏洞描述 /AjaxService/Upload.aspx 存在任意文件上传漏洞 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公共秩序,尊重社会公德,不得利用网络从事危害国家安全、荣誉和利益,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作…...

MYSQL篇--锁机制高频面试题

Mysql锁机制 1对mysql的锁有了解吗? 首先我们要知道,mysql的锁 其实是为了解决在并发事务时所导致的数据不一致问题的一种处理机制,也就是说 在事务的隔离级别实现中,就需要利用锁来解决幻读问题 然后我们可以聊到锁的分类 按锁…...

创建一个郭德纲相声GPTs

前言 在这篇文章中,我将分享如何利用ChatGPT 4.0辅助论文写作的技巧,并根据网上的资料和最新的研究补充更多好用的咒语技巧。 GPT4的官方售价是每月20美元,很多人并不是天天用GPT,只是偶尔用一下。 如果调用官方的GPT4接口&…...

靶机实战(10):OSCP备考之VulnHub Tre 1

靶机官网:Tre: 1[1] 实战思路: 一、主机发现二、端口发现(服务、组件、版本)三、漏洞发现(获取权限) 8082端口/HTTP服务 组件漏洞URL漏洞(目录、文件)80端口/HTTP服务 组件漏洞URL漏…...

在windows11系统上利用docker搭建linux记录

我的windows11系统上,之前已经安装好了window版本的docker,没有安装的小伙伴需要去安装一下。 下面直接记录安装linux的步骤: 一、创建linux容器 1、拉取镜像 docker pull ubuntu 2、查看镜像 docker images 3、创建容器 docker run --…...

swift对接环信sdk

准备 熟练objective-c语言 有一台mac电脑,并安装了xcode 和 cocoapods 内容篇幅较长,需要内心平和耐心看下去,务必戒躁. 学习目的 手把手教大家如何在iOS应用中集成环信IM 明确表示,内容一定全面,没有任何丢失,只要沉得住气,耐得下心,3小时即可搞定. 若经常阅读文档以及语…...

单片机中的PWM(脉宽调制)的工作原理以及它在电机控制中的应用。

目录 工作原理 在电机控制中的应用 脉宽调制(PWM)是一种在单片机中常用的控制技术,它通过调整信号的脉冲宽度来控制输出信号的平均电平。PWM常用于模拟输出一个可调电平的数字信号,用于控制电机速度、亮度、电压等。 工作原理 …...

css 怎么绘制一个带圆角的渐变色的边框

1&#xff0c;可以写两个样式最外面的div设置一个渐变的背景色。里面的元素使用纯色。但是宽高要比外面元素的小。可以利用里面的元素设置padding这样挡住部分渐变色。漏出来的渐变色就像边框一样。 <div class"cover-wrapper"> <div class"item-cover…...

Kotlin DSL C++项目引入OpenCV异常处理

现象 kotlin DSL(build.rgadle.kts)项目引入openCV sdk 编译提示Plugin [id: com.android.application, version: 8.2.1...错误 Plugin [id: com.android.application, version: 8.2.1, apply: false] was not found in any of the following sources:* Try: > Run with -…...

【微服务】 Spring cold、Kubernetes、Service mesh

目录 Spring Cloud # 什么是微服务&#xff1f;谈谈你对微服务的理解&#xff1f; # 什么是Spring Cloud&#xff1f; # springcloud中的组件有那些&#xff1f; # 具体说说SpringCloud主要项目? # Spring Cloud 和dubbo区别? # 服务注册和发现是什么意思&#xff1f;S…...

【scala】编译build报错 “xxx is not an enclosing class“

private[sources] val creationTimeMs: Long {val session SparkSession.getActiveSession.orElse(SparkSession.getDefaultSession)require(session.isDefined)private[xxx]是访问权限控制在xxxx包的意思。 解决办法&#xff1a; 把[sources]删掉&#xff0c;或者改成和包名…...

vue3+ts+vite项目从0 搭建,配置安装router/pinia/element-plus/scss等

一、安装vite环境 官网&#xff1a;https://cn.vitejs.dev/guide/why.html npm init vite1.选择vue 2.选择typescipt 3.创建成功 默认项目结构如下 4.安装项目依赖 npm install 5.启动项目 npm run dev二。安装配置scss 1.运行安装scss npm install -D sass sass-loa…...

华为OD机试 - 矩阵匹配(Java JS Python C)

题目描述 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式: N M K N*M矩阵 输出描述 N*M 的矩阵中可以选出 M! / N! 种组合数…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

规则与人性的天平——由高考迟到事件引发的思考

当那位身着校服的考生在考场关闭1分钟后狂奔而至&#xff0c;他涨红的脸上写满绝望。铁门内秒针划过的弧度&#xff0c;成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定"&#xff0c;构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...

Appium下载安装配置保姆教程(图文详解)

目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...

Element-Plus:popconfirm与tooltip一起使用不生效?

你们好&#xff0c;我是金金金。 场景 我正在使用Element-plus组件库当中的el-popconfirm和el-tooltip&#xff0c;产品要求是两个需要结合一起使用&#xff0c;也就是鼠标悬浮上去有提示文字&#xff0c;并且点击之后需要出现气泡确认框 代码 <el-popconfirm title"是…...

2025-06-01-Hive 技术及应用介绍

Hive 技术及应用介绍 参考资料 Hive 技术原理Hive 架构及应用介绍Hive - 小海哥哥 de - 博客园https://cwiki.apache.org/confluence/display/Hive/Home(官方文档) Apache Hive 是基于 Hadoop 构建的数据仓库工具&#xff0c;它为海量结构化数据提供类 SQL 的查询能力&#xf…...