Mac 下 Python+Selenium 自动上传西瓜视频
背景
研究下 Python+Selenium 自动化测试框架,简单实现 Mac 下自动化批量上传视频西瓜视频并发布,分享给需要的同学(未做过多的异常处理)。
脚本实现
首先通过手工手机号登录,保存西瓜视频网站的 cookie 文件
之后加载 cookie 内容,使用脚本批量上传视频,保存到草稿(也可自动发布,为了二次编辑,如修改封面)
最后通过遍历视频草稿列表,来进行草稿视频发布,PS: 同一天上传或发布视频太多时,会被西瓜视频限流。
安装依赖
# 安装依赖保存网站 cookie# 安装 chromedriver
$ brew install chromedriver
脚本内容
#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
import json
import os
import shutil
import sysfrom selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver import ActionChains
from pykeyboard import PyKeyboard
from pymouse import PyMouse
import pyperclipclass XiGua:"""Mac 西瓜视频自动上传视频及发布草稿"""def __init__(self):"""初始化,打开浏览器"""self.driver = webdriver.Chrome()def save_cookies(self, cookies_file_name):"""保存 cookiescookies_file_name: cookies 文件名称"""# 预留 20 秒,来进行手工登录time.sleep(20)# 登录成功后,保存 cookies 文件with open(cookies_file_name, 'w') as cookies_file:cookies_file.write(json.dumps(self.driver.get_cookies()))def load_cookies(self, cookies_file_name):"""加载 cookiecookies_file_name: cookies 文件名称"""# 加载 cookies 文件with open(cookies_file_name, 'r') as cookies_file:cookies_list = json.load(cookies_file)for cookie in cookies_list:if 'expiry' in cookie:del cookie['expiry']self.driver.add_cookie(cookie)# 加载 cookie 后,刷新页面生效self.driver.refresh()def is_exist_element_by_xpath(self, xpath):"""判断元素是否存在"""flag = Truetry:self.driver.find_element_by_xpath(xpath)return flagexcept Exception as e:flag = Falseprint("xpath: [%s] 的元素不存在,错误:%s" % xpath, e)return flagdef upload_video(self, video_file_path):"""上传视频video_file_path: 上传视频路径"""# 打开上传视频页面self.driver.get("https://studio.ixigua.com/upload?from=post_article")# 点击上传self.driver.find_element_by_class_name("byte-upload-trigger-drag").click()time.sleep(5)# 选择视频文件k = PyKeyboard()m = PyMouse()# 打开k.press_keys(['Command', 'Shift', 'G'])x_dim, y_dim = m.screen_size()k.press_keys(['Shift'])m.click(x_dim // 2, y_dim // 2, 1)# 复制视频文件路径pyperclip.copy(video_file_path)# 粘贴k.press_keys(['Command', 'V'])time.sleep(2)k.press_key('Return')time.sleep(2)k.press_key('Return')time.sleep(2)# 设置转载选项self.driver.find_element_by_xpath('//*[@id="js-video-list-content"]/div/div[2]/div[4]/div[2]/div/div/label[2]/span/span').click()time.sleep(1)# 同步到抖音# self.driver.find_element_by_class_name("byte-checkbox-mask").click()# 循环判断视频上传成功,不成功等待10秒后,再次判断,直到成功while '上传成功' not in self.driver.find_element_by_xpath('//*[@id="js-video-list-content"]/div/div[1]/div[1]/div[2]/div[2]').text:print("循环等待视频上传成功,等待10秒")time.sleep(10)# 设置视频封面self.driver.find_element_by_class_name("m-xigua-upload").click()print('点击-上传封面')time.sleep(5)try:reload = self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div[1]/div/div/div/div[2]')# 视频封面解析失败处理,循环刷新if reload != '':print('视频封面解析失败处理,开始循环刷新')while XiGua.is_exist_element_by_xpath(self,'/html/body/div[3]/div/div[2]/div/div[1]/div/div/div/div[2]'):# 点击循环self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div[1]/div/div/div/div[2]').click()print('刷新失败后,等待5秒,再次刷新')time.sleep(5)# 选择第一个图片img = self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div[1]/div/div/div[1]/img')img.click()except Exception as e:print('封面解析正常,无需刷新')pass# 下一步cover_next_element = WebDriverWait(self.driver, 30).until(lambda x: x.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div[2]/div'))cover_next_element.click()print('点击-封面下一步')try:# 完成裁剪cover_crop_element = WebDriverWait(self.driver, 30).until(lambda x: x.find_element_by_xpath('//*[@id="tc-ie-base-content"]/div[2]/div[2]/div[2]/div/div[2]/div/div/div[2]'))if cover_crop_element != '':cover_crop_element.click()print('点击-封面完成裁剪')else:print('封面无需裁剪')except Exception as e:print('裁剪封面出现异常:%s' % e)passtime.sleep(5)# 确定self.driver.find_element_by_xpath('//*[@id="tc-ie-base-content"]/div[2]/div[2]/div[3]/div[3]/button[2]').click()print('点击-封面确定')time.sleep(1)# 再次确定self.driver.find_element_by_xpath('/html/body/div[4]/div/div[2]/div/div[2]/button[2]').click()print('点击-封面再次确定')time.sleep(5)# 存草稿draft_element = WebDriverWait(self.driver, 30).until(lambda x: x.find_element_by_xpath('//*[@id="js-submit-draft-0"]/button'))action = ActionChains(self.driver)print('点击-保存草稿')# 移动滚动条到底部js = "window.scrollTo(0,document.body.scrollHeight)"self.driver.execute_script(js)# 移动到 存草稿 按钮点击action.move_to_element(draft_element).click().perform()def close(self):"""关闭浏览器"""self.driver.close()def batch_upload(self, videos_dir_path):"""批量上传视频videos_dir_path: 上传视频存储路径"""files = os.listdir(videos_dir_path)# 降序排序上传,草稿发布时,视频序号则为顺序files.sort(reverse=True)# 批量上传视频for file in files:if os.path.splitext(file)[1] == '.mp4':full_file_path = os.path.join(videos_dir_path, os.path.splitext(file)[0])print("==开始上传视频:%s" % full_file_path)self.upload_video(full_file_path)src = os.path.join(videos_dir_path, file)dst = os.path.join(videos_dir_path, 'bak', file)# 发布完成后,移到到备份目录shutil.move(src, dst)def videos_release(self):"""草稿视频发布"""self.driver.get("https://studio.ixigua.com/content")time.sleep(2)# 点击草稿导航draft_navigation_element = WebDriverWait(self.driver, 30).until(lambda x: x.find_element_by_xpath('//*[@id="app"]/div/section/div/div[1]/ul/li[3]'))draft_navigation_element.click()print('点击-草稿导航')time.sleep(2)# 草稿列表draft_elements = self.driver.find_elements_by_class_name('content-card__title ')# 草稿列表为空,则退出if len(draft_elements) == 0:print("草稿列表为空")XiGua.close(self)sys.exit()# 循环发布草稿,每次都发布第一个for i in range(1, 99999):# 草稿列表为空,退出if draft_elements == '':print('草稿发布完成,总共:%s' % str(i))XiGua.close(self)sys.exit()print('当前发布数量 %s, 发布视频: %s' % (str(i), draft_elements[0].text))# 发布草稿第一个视频draft_elements[0].click()time.sleep(3)# 立即发布element2 = WebDriverWait(self.driver, 30).until(lambda x: x.find_element_by_xpath('//button[contains(text(), "发布")]'))element2.click()print('点击-视频发布')# 判断是否发布失败,如标题超长try:# 错误处理if XiGua.is_exist_element_by_xpath(self, '/html/body/div[3]/div/div/div/span'):print('发布出现错误,退出,请检查错误,如标题超长等')sys.exit()except Exception as e:print('草稿发布异常:%s' % e)pass# 处理封面分辨率低提示try:# 封面分辨率低cover_cancel_element = self.driver.find_element_by_xpath('//div[contains(text(), "取消")]')print('封面分辨率低处理,直接取消')# 错误处理if cover_cancel_element != '':print('取消封面分辨率低')cover_cancel_element.click()# 立即发布cover_publish_element = WebDriverWait(self.driver, 30).until(lambda x: x.find_element_by_xpath('//button[contains(text(), "发布")]'))cover_publish_element.click()except Exception as e:print('封面分辨率低出现异常:%s' % e)pass# 点击草稿draft_publish_element = WebDriverWait(self.driver, 30).until(lambda x: x.find_element_by_xpath('//*[@id="app"]/div/section/div/div[1]/ul/li[3]'))draft_publish_element.click()time.sleep(2)print('重新获取草稿列表')draft_elements = self.driver.find_elements_by_class_name('content-card__title ')print(draft_elements)def xigua_videos_release(self, base_url, cookies_file_path):"""西瓜视频发布草稿base_url: 西瓜视频网站cookies_file_path: 西瓜视频 cookies 文件路径"""self.driver.get(base_url)# 加载 cookiesXiGua.load_cookies(self, cookies_file_path)# 草稿发布视频XiGua.videos_release(self)# 关闭浏览器XiGua.close(self)def xigua_batch_upload(self, base_url, cookies_file_path, videos_dir_path):"""西瓜视频批量发布视频base_url: 西瓜视频网站cookies_file_path: 西瓜视频 cookies 文件路径videos_dir_path: 上传视频存储路径"""self.driver.get(base_url)XiGua.load_cookies(self, cookies_file_path)XiGua.batch_upload(self, videos_dir_path)XiGua.close(self)def xigua_save_cookies(self, base_url, cookies_file_path):"""保存网站 cookiebase_url: 网站地址cookies_file_path: 网站 cookies 文件路径"""self.driver.get(base_url)# 保存 cookiesXiGua.save_cookies(self, cookies_file_path)XiGua.close(self)if __name__ == '__main__':xi_gua = XiGua()# 西瓜视频base_url = 'https://www.ixigua.com/'xigua_cookies = '/tmp/xigua_update_video/xigua_cookies.txt'videos_dir_path = '/tmp/rm'## 1. 保存 cookie# xi_gua.xigua_save_cookies(base_url, 'xigua_cookies.txt')## 2. 批量上传xi_gua.xigua_batch_upload(base_url, xigua_cookies, videos_dir_path)## 3. 批量发布草稿# xi_gua.xigua_videos_release(base_url, xigua_cookies)
行动吧,在路上总比一直观望的要好,未来的你肯定会感 谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入扣群: 320231853,里面有各种软件测试+开发资料和技术可以一起交流学习哦。
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
相关文章:
Mac 下 Python+Selenium 自动上传西瓜视频
背景 研究下 PythonSelenium 自动化测试框架,简单实现 Mac 下自动化批量上传视频西瓜视频并发布,分享给需要的同学(未做过多的异常处理)。 脚本实现 首先通过手工手机号登录,保存西瓜视频网站的 cookie 文件 之后加载…...
六:ReentrantLock —— 可重入锁
目录 1、ReentrantLock 入门2、ReentrantLock 源码解析2.1、构造方法:默认为非公平锁2.2、三大内部类2.2、lock():加锁【不可中断锁】2.2.1、acquire() 方法 —— AQS【模板方法】2.2.2.1 tryAcquire() 方法 —— AQS,由子类去实现2.2.2.2. a…...
一种驱动器的功能安全架构介绍
下图提供了驱动器实现安全功能的架构 具有如下特点: 1.通用基于总线或者非总线的架构。可以实现ethercat的FSOE,profinet的profisafe,或者伺服本体安全DIO现实安全功能。 2.基于1oo2D架构,安全等级可以达到sil3。 3.高可用性。单…...
紫光展锐T610平台_4G安卓核心板方案定制开发
紫光展锐T610核心板配备Android 11操作系统,采用12nm制程工艺。该处理器CPU由2颗基于Cortex-A75架构的大核心和6颗基于Cortex-A55架构的小核心组成,最高主频为1.8GHz。GPU采用的是614.4MHz的Mali G52,可以流畅播放2400*1080分辨率视频&#x…...
C++11 设计模式4. 抽象工厂(Abstract Factory)模式
问题的提出 从前面我们已经使用了工厂方法模式 解决了一些问题。 现在 策划又提出了新的需求:对于各个怪物,在不同的场景下,怪物的面板数值会发生变化, //怪物分类:亡灵类,元素类,机械类 …...
第8周 Python面向对象编程刷题
单击题目,直接跳转到页面刷题,一周后公布答案。加入QQ群701657573,随时答疑交流。 218:类对象属性219:坐标对象相加220:计算周长221:学生分数总和222:车辆类中创建引擎类对象223&am…...
【学习心得】神经网络知识中的符号解释②
我在上篇文章中初步介绍了一些神经网络中的符号,只有统一符号及其对应的含义才能使我自己在后续的深度学习中有着一脉相承的体系。如果对我之前的文章感兴趣可以点击链接看看哦: 【学习心得】神经网络知识中的符号解释①http://t.csdnimg.cn/f6PeJ 一、…...
Igh related:Small Bug And Notes Record.
Write at the top My computer got some silly problem with the typing software that my Chinese IM does’t work again. So I’ll try to record the things happened in English. If any error,DM me plz. BUGs BUG1 Undefined symbol Identifier “CLOCK_MONOTONIC”…...
【QT入门】Qt自定义控件与样式设计之qss介绍(Qt style sheet)
往期回顾: 【QT入门】 无边框窗口设计之实现圆角窗口-CSDN博客【QT入门】 无边框窗口设计综合运用之自定义标题栏带圆角阴影的窗口-CSDN博客 【QT入门】 无边框窗口设计之综合运用,实现WPS的tab页面-CSDN博客 【QT入门】Qt自定义控件与样式设计之qss介绍…...
[ LeetCode ] 题刷刷(Python)-第49题:字母异位词分组
题目描述 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词是由重新排列源单词的所有字母得到的一个新单词。 即将含有相同字符但排列顺序不同的字符串放入同一个组中。 示例 示例 1: 输入: strs ["eat", &qu…...
冒泡排序算法实现步骤
算法实现的过程: 1. 定义问题: - 算法是用来解决某一特定计算问题的方法步骤。例如,对于排序问题,我们需要一个算法对一组无序的整数进行排序。 2. 设计算法: - 冒泡排序是一种基础的排序算法。它的设计思路是…...
js实现webp转png/jpg
网上保存的图片是webp类型的,但是我把它嵌入flac格式的音频里后导致网页中无法播放 wps要会员,真麻烦。 完整代码: <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8">…...
DVWA -File Upload-通关教程-完结
DVWA -File Upload-通关教程-完结 文章目录 DVWA -File Upload-通关教程-完结页面功能LowMediumHighImpossible 页面功能 此页面的功能为选择某个图片文件点击Upload按钮上传,上传成功后得知文件上传路径为DVWA\hackable\uploads。 Low 源码审计 这段 PHP 代码…...
中介者模式:简化对象间通信的协调者
在面向对象的软件开发中,中介者模式是一种重要的行为型设计模式,用于降低多个对象间通信的复杂性。通过提供一个中心化的对象来处理不同组件之间的交互,中介者模式使得组件间不必显式引用彼此,从而使其松散耦合、更易于维护。本文…...
【Python系列】pydantic版本问题
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
深度学习-多尺度训练的介绍与应用
一、引言 在当今快速发展的人工智能领域,多尺度训练已经成为了一种至关重要的技术,特别是在处理具有复杂结构和不同尺度特征的数据时。这种技术在许多应用中发挥着关键作用,例如图像识别、自然语言处理和视频分析等。 多尺度训练的定义 多尺…...
详解单文件组件
当你创建 Vue 单文件组件时,通常会包含三个部分:<template>、<script> 和 <style>。这三个部分分别用于定义组件的模板、逻辑和样式。让我更详细地解释一下它们的作用和用法: <template> <template> 标签用于…...
MLeaksFinder报错
1.报错:FBClassStrongLayout.mm 文件:layoutCache[currentClass] ivars; 解决:替换为layoutCache[(id)currentClass] ivars; 2.编译正常但运行时出现crash indirect_symbol_bindings[i] cur->rebinding FBRetainCycleDetector iOS15 …...
【心路历程】初次参加蓝桥杯实况
送给大家一句话: 寂静的光辉平铺的一刻,地上的每一个坎坷都被映照得灿烂。 – 史铁生 《我与地坛》 初次参加蓝桥杯有感 一点小小的震撼难评的做题过程A题 艺术与篮球问题描述解题 B 题 五子棋问题描述解题 C题 训练士兵问题描述解题 D题 团建解题 E题 …...
微信小程序全屏开屏广告
效果图 代码 <template><view><!-- 自定义头部 --><u-navbar title" " :bgColor"bgColor"><view class"u-nav-slot" slot"left"><view class"leftCon"><view class"countDown…...
记录day1
1.早上 ①协同过滤算法 基于物品基于用户分别是如何实现的 相似度的计算方式 基于用户和基于物品的区别 实时性和新物品这里: 实时性指的是用户有新行为,这样基于物品就好,因为用户新行为了,用户矩阵不会变化,用户…...
stm32GPio的开发基础
上拉输入:高电平(弱高电平,一般默认) 下拉输入:低电平 没有上拉下拉就是处于一个不确定的状态 推挽wan输出:驱动能力比较强,推挽是因为往外推 set就是1,reset就是0 XMX就是封装的…...
DataSource
目录 1、 DataSource 1.1、 * 建立数据库连接的参数对象 1.1.1、 * 数据库url 1.1.2、 * 数据库用户名 1.1.3、 * 数据库密码 1.1.4、 * 数据库驱动名称 <...
Linux防止暴力破解密码脚本
1.认识记录linux记录安全的日志 [roottestpm ~]# cd /var/log/ [roottestpm log]# ls | grep secure secure 2.该日志的内容查看 [roottestpm log]# tail -f secure #表示ssh身份验证失败 Aug 29 23:35:03 testpm sshd[111245]: pam_unix(sshd:auth): authentication fa…...
Unity 遮罩
编辑器版本 2017.2.3f1 学习Unity的三张遮罩方式 1. Mask 遮罩方式 首先,在界面上创建2个Image,一个命名Img_Mask,大小设置 400* 400, 一个命名Img_Show,大小设置500*500。 然后,给 Img_Mask添加Mask,选择Img_Mask,点击Add Com…...
jmeter实验 模拟:从CSV数据到加密请求到解密返回数据再到跨越线程组访问解密后的数据
注意,本实验所说的加密只是模拟加密解密,您需要届时写自己的加解密算法或者引用含有加密算法的相关jar包才行. 思路: 线程组1: 1.从CSV文件读取原始数据 2.将读取到的数据用BeanShell预习处理器进行加密 3.HTTP提取器使用加密后的数据发起请求 4.使用BeanShell后置处理器…...
设计模式——外观(门面)模式10
外观模式:能为系统框架或其他复杂业务流程封装提供一个简单的接口。 例如抽奖过程中 设计模式,一定要敲代码理解 调用1(抽奖系统) /*** author ggbond* date 2024年04月08日 10:34*/ public class Lottery {public String getId…...
第七周周一人工智能导论预告
第一讲 人工智能概述 1.1 简介 1.2人工智能的概念 1.3 人工智能的发展简史 1.4 人工智能研究的基本内容 第一讲 人工智能概述单元测试 第二讲 一阶谓词逻辑表示法 2.1 命题逻辑 2.2 谓词逻辑 2.3 一阶谓词逻辑知识表示法 第二讲 一阶谓词逻辑知识表示法单元测试 第…...
npm install 的不同选项:--save、--save-dev、-S、-D 的区别
Node.js 的包管理器 npm 提供了一个命令 npm install,用于安装 Node.js 项目所需的依赖包。在使用这个命令时,我们可以通过添加不同的选项来控制依赖包的安装方式。本文将详细介绍这些选项:--save、--save-dev、-S 和 -D 的区别。 1. --save…...
设计模式详解(十四)——策略模式
策略模式简介 策略模式定义 策略模式(Strategy Pattern)是一种行为型设计模式,它使能在运行时改变对象的行为。策略模式属于对象行为模式,它定义了一系列的算法,并将每一个算法封装起来,使它们可以互相替换…...
电商专业网站建设的毕业设计/北京seo优化推广
技术解决:(即设计阶段,包括系统设计,详细设计等) 目的:“技术解决”的目的在于开发、设计和实现满足需求的解决方案。解决方案的设计和实现等都围绕产品、产品构件和与过程相关的产品(可能是其中…...
北京网站设计与制作/cnzz站长统计工具
最近比较关注学习Python方面的资料和课程,由于Python本身基本都是在Linux下开发,本人windows用习惯了初用Linux各种别扭啊。下面将我在配置Windows环境下的禁言写出来,与大家分享。1.下载与安装Python1.Python官方网址:https://ww…...
wordpress修改固定连接404/宁波如何做seo排名优化
1.重启之前最好先看一下节点信息和运行状态 可以通过srvctl status database -d 数据库名 //查看节点信息 Crs_stat //查看节点状态 可以看到数据节点它由两个实例组成一个数据库,分别运行不同的节点,且状态ok 2.首先关闭数据库 Srvctl stop database -d…...
学做网站需要多长时间/公司网站建设
如何让报表中的Table按自己的需要来分页?例如,每20行就强制分页。 方法: 1. 在Table中添加一个分组,分组表达式为 (RowNumber("Table1") - 1) / 20 2. 去掉分组组头 3. 在分组属性中选择checkbox "在结尾处分页…...
海口小程序开发/正规seo关键词排名网络公司
文章目录公共字段自动填充问题分析基本功能实现思路分析代码实现功能测试功能完善思路分析ThreadLocal操作步骤代码实现功能测试思维导图总结新增分类需求分析数据模型前端页面分析代码实现功能测试分类信息分页查询需求分析前端页面分析代码实现功能测试思维导图总结删除分类需…...
网站建设活动策划/seo 培训教程
休假了,有时间测试下12C的新功能了,今天测试下分页查询。在12C之前,要想分页查询,我们通常会用下面的SQL。SQL> select *2 from (select a.*, rownum rn3 from (select id,4 username5 from top_test) a6 where rn < 10)7 w…...