躺着就能涨粉?Python自动化短视频搬运(六)|自动发布

脚本四:视频自动发布到平台

好了,影片、封面、标题及实时频道监测,一切准备就绪,我们终于来到了自动化搬运脚本的最后一步:发布。由于可发布的自媒体平台众多,我们需要针对每个平台的Web结构编写独立的脚本,这部分有不少的工作量。但好在这些平台的HTML样式及交互流程基本类似,熟悉了自动发布脚本的编写方法后,扩展到任何一个平台都没有什么难度。

1. Selenium(浏览器自动化工具)

首先,我们先得了解一个大前提,所有平台的视频上传对于脚本来说都只能通过web端进行,并不是通过APP端,但好在他们都提供了web版的“创作中心”。自动发布脚本之所以能自动发布视频的核心原理是让浏览器可以模拟真人进行网页操作,从而完成整个视频上传发布流程。那么接下来就让我隆重推出这个用来模拟用户在浏览器上动作的第三方开源工具-Selenium。

Selenium 是一系列工具和库的综合项目,这些工具和库支持 web 浏览器的自动化。

常见的Selenium执行动作有:将文本输入到字段中,选择下拉值和复选框,并单击文档中的链接。 它还提供许多其他控件,比如鼠标移动、任意 JavaScript 执行等等。虽然Selenium主要用于网站的前端测试,但像我们这样用于网页自动化的项目,也是一个很好的选择。

让我们先用pip安装Selenium:

$ pip install selenium

WebDriver

使用Selenium的核心就是WebDriver,我们需要根据想要操作的浏览器类型,下载对应的WebDriver驱动文件,如Firefox的geckodriver:https://github.com/mozilla/geckodriver/releases,Chrome的chromedriver:https://chromedriver.chromium.org/downloads。对应找到符合你操作系统类型的驱动文件,进行下载。我这篇文章中的案例将采用Firefox浏览器进行。

导入WebDriver后,我们就可以尝试让Selenium快速打开一个网页了(就用快手平台的创作者中心吧):

from selenium import webdriver
driver = webdriver.Firefox(executable_path = './geckodriver')
driver.get("https://cp.kuaishou.com/article/publish/video")

地址栏背景变成红色且出现机器人图标,说明这个页面是由自动化脚本打开的:



你可能会注意到,每次由selenium访问网站时都需要重新登录,即使上一次已经登录成功。那是因为,每次调用webdriver生成一个新的访问session时,浏览器都会为这次session新建一个profile目录,用以存储网页缓存和登录状态,cookie等,因此之前访问过的登录信息默认不会被传递过来。由于我们的脚本是要求浏览器保留登录状态的,避免需要人工介入登录,因此我们要调用webdriver中的profile指定路径的功能,使每次新的访问session都能够获取到已经存在的登录状态,从而跳过登录页面。

首先,我们要找到Firefox默认的profile存放地址,方法是:

  1. 打开Firefox

  2. 地址栏输入about:support

  3. 找到Profile Folder行即是profile存放地址



    有了这个目录地址,使用以下代码拷贝该地址到webdriver的profileDir里:

from selenium import webdriver 
profileDir = r'/Users/yeyu/Library/Application Support/Firefox/Profiles/czstyl61.default-release/'
profile = webdriver.FirefoxProfile(profileDir)
driver = webdriver.Firefox(executable_path = './geckodriver', firefox_profile = profile) 
driver.get("https://cp.kuaishou.com/article/publish/video")

最后,不要忘了手动打开一次 https://cp.kuaishou.com/article/publish/video,通过手机扫码或输入用户名密码,成功登录一次快手平台,生成profile,以后只要登录信息不过期,selenium每次新建网页session时,都能直接进入上传页面而不需要再进行登录了。

2. 自动脚本的基本编写过程

在编写代码前,让我们以最简单的方式了解怎么写一个自动脚本,总结下来就是以下两步:

  • 读取需要进行交互的HTML组件标记
  • 对该标记进行状态判断(clickable)、写入(Send keys)或点击(Click)

参考下图,以Firefox为例,读取HTML组件标记只需要 1)鼠标右击需要操控的HTML组件, 2)点击菜单里Inspect(检查)项,3)读取Inspector窗口中高亮的标记内容,如button类型,class名称等等。


读取web组件标记步骤

虽然我们创建的driver对象有find_element()方法能够找到并生成组件对象,但是在一般的网络交互中,页面打开的时间受网速等很多因素影响,当一个页面切换的时候,无法保证下一个页面中我们感兴趣的元素能够多久刷新出来,因此直接使用find_element()配合固定延时,不是很高效。Selenium提供了一个很实用的WebDriverWait(driver, timeout).until()方法,可以在给定的时间里等待元素可用,一旦可用就立即返回元素对象。对于上面的“上传视频”按钮,直接看代码,我们用到了CSS_SELECTOR来定位button类型元素的class名称:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

button = WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                                                      "button[class='SOCr7n1uoqI-']")))
button.click()

不单是button类型,其他的类型如div等都是支持click()的。另外,input类型包括text/file,都可以send_keys()进行输入操作。这部分会在后面的实际平台操作中详细介绍。

3. 快手平台上传发布

打开快手上传页面:快手创作者服务平台

视频文件上传

根据上两个章节讲到的,免去登录流程后,首先映入眼帘的就是“上传视频”按钮,找到它的组件元素:button class=“SOCr7n1uoqI-”,我们用WebDriverWait等待这个页面的刷新,由于这个页面主要是视频文件输入框,所以我们的脚本并不需要去button.click(),而是找到type为file的input元素,向它输入我们需要上传的视频文件即可:

button = WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                                                      "button[class='SOCr7n1uoqI-']")))
search = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
search.send_keys("<文件路径>/v1080p_audio_output.mp4")

运行后,你就能看到下一个页面,并且文件正在上传中,等待一会,就看到了文件上传成功:


上传成功

那么如何用代码判断上传成功呢?同样的我们找到这个“上传成功”文字的HTML标记,得到它是span类型的类名为"DqNkLCyIyfQ-"。



所以我们就用一个while循环来等待这个span标记的出现,从而第一时刻获知视频文件的上传成功。
while "上传成功" != driver.find_element(By.CSS_SELECTOR, "span[class='DqNkLCyIyfQ-']").get_attribute("innerHTML"):
    time.sleep(3)

封面上传

视频上传成功后,我们就可以开始上传在上一篇文章中制作好的封面图片了。首先找到“编辑封面”的HTML元素,<button class="ant-btn ant-btn-primary"...>:



点击操作,代码:

WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                                       "button[class='ant-btn ant-btn-primary']"))).click()

在下个页面找到“上传封面”标签的HTML元素,<div id="rc-tabs-1-tab-2"...>:


上传封面

点击操作,代码:

WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                                              "div[id='rc-tabs-1-tab-2']"))).click()

再进入到下一个页面后,又来到了熟悉的文件输入页了,对于<button class="ant-btn ant-btn-primary xJ4CDDyNkAs-"...>我们就无需再点击了,只要等它的出现,然后直接对<input type="file"...>进行文件路径输入即可:


上传封面图片

我们就使用上一篇制作的封面“v1080p_audio_output_with_title.jpeg”进行上传,代码部分:

WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[class='ant-btn ant-btn-primary xJ4CDDyNkAs-']")))
search_list = driver.find_elements(By.CSS_SELECTOR, "input[type='file']")
search_list[1].send_keys("<文件路径>/v1080p_audio_output_with_title.jpeg")

最后,在下一个页面中,点击“确定”按钮:



代码:

WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                          "button[class='ant-btn ant-btn-primary TyKzAKboOM0-']"))).click()

填写描述

上传完了视频和封面图片,最后一个需要输入的就是视频描述了,这个就很简单了。找到输入框的HTML元素标记 <div class="clGhv3UpdEo-"...>:



调用send_keys()输入text即可,这里我们就用封面使用的文字“一段不错的舞蹈!”。假设你搬运的都是同一个主题,另外还可以加入一些固定的标签,这里举例如“#小哥哥跳舞 #国外舞蹈达人”:

title_input = WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[class='clGhv3UpdEo-']")))
title_input.send_keys("一段不错的舞蹈!")
title_input.send_keys("#小哥哥跳舞 #国外舞蹈达人")

此外,在实际代码开发中,还应该考虑到文本框的字数或视频大小限制等其他边界处理,这里就不展开了。

发布

所有必要的内容都输入完毕,页面上还有一些其他的选项,暂时不必去改动,让我们直接点击发布按钮,


发布按钮

最终发布前我们可以做一个一分钟的延时,避免由于网络问题导致封面没有来得及上传成功,上代码:

import time

time.sleep(60)
WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                        "button[class='ant-btn ant-btn-primary GncXo-rrppc-']"))).click()

如果看到跳转到以下的页面,说明脚本自动化发布视频到快手平台已经完成!


总结

至此,我们的整个自动化搬运流程走完了,通过这个系列的文章,整个过程包括频道监测->影片下载->影片处理->自媒体发布,都做了比较详细的介绍和源代码提供。后面还会为大家添加抖音等其他热门平台的自动化脚本,不过如果按照这篇文章走完了快手流程,相信你自己也可以很快复制出其他平台的上传脚本的。此外,后续还会提供从其他国外平台进行搬运的教程,敬请期待吧!

本篇用到的代码:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import time

profileDir = '<修改为你的Firefox的profile目录>'
profile = webdriver.FirefoxProfile(profileDir)
driver = webdriver.Firefox(executable_path = '<修改为你的webdriver文件路径>/geckodriver', firefox_profile = profile)
driver.get("https://cp.kuaishou.com/article/publish/video")

#视频上传
button = WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                                                      "button[class='SOCr7n1uoqI-']")))
file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
file_input.send_keys("<修改为你的视频文件路径>/v1080p_audio_output.mp4")
while "上传成功" != driver.find_element(By.CSS_SELECTOR, "span[class='DqNkLCyIyfQ-']").get_attribute("innerHTML"):
    time.sleep(3)

#封面上传
WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                                       "button[class='ant-btn ant-btn-primary']"))).click()
WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                                              "div[id='rc-tabs-1-tab-2']"))).click()
WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                                       "button[class='ant-btn ant-btn-primary xJ4CDDyNkAs-']")))
search_list = driver.find_elements(By.CSS_SELECTOR, "input[type='file']")
search_list[1].send_keys("<修改为你的封面图片文件路径>/v1080p_audio_output_with_title.jpeg")
WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                          "button[class='ant-btn ant-btn-primary TyKzAKboOM0-']"))).click()
#填写描述
title_input = WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[class='clGhv3UpdEo-']")))
title_input.send_keys("一段不错的舞蹈!")
title_input.send_keys("#小哥哥跳舞 #国外舞蹈达人")

#发布
time.sleep(60)
WebDriverWait(driver, 150).until(EC.element_to_be_clickable((By.CSS_SELECTOR, \
                        "button[class='ant-btn ant-btn-primary GncXo-rrppc-']"))).click()

publish.py

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容