Youtube + Selenium ChromeDriver (Python) - 如何知道视频何时结束?
Youtube + Selenium ChromeDriver (Python) - How to know when a video ends?
[编辑:已解决,请参阅问题文本的中途]
关于理解其中播放视频的 Youtube 页面内容的快速问题:
总结
我使用 Selenium 在 Youtube 上播放视频,作为基于浏览器的 GUI 的一部分。
我需要知道视频何时播放完毕,以便 GUI 执行其他操作(例如将本地 HTML 馈送到浏览器)。
代码段和问题
import os, time
from selenium import webdriver
# [...]
chromedriver = 'path_to_chromedriver_binary' # substitute as appropriate
driver = webdriver.Chrome(chromedriver)
youtube_link = 'https://www.youtube.com/watch?v=somevideo'
driver.get(youtube_link)
至此,我可以time.wait()
视频的长度。
但是,我想知道我是否可以通过 Selenium 驱动程序查询 YouTube 页面并在 while 循环中计算剩余播放时间(我不熟悉如何从 youtube 页面提取此信息)
谢谢!
[用解决方案编辑]
硒溶液
感谢 Stanjer,感谢 this answer and this other answer,您可以通过此方法获得 movie_player
状态:
player_status = driver.execute_script("return document.getElementById('movie_player').getPlayerState()")
(别忘了在脚本开头加上"return")
Selenium 替代解决方案
不够优雅但值得指出:
driver.text
returns 表示此字符串格式 '1:00 / 2:00' 中的视频计时器的字符串。因此,您可以通过以下方式检查视频是否播放完毕:
video_is_playing = True
while video_is_playing:
time.sleep(1)
video_is_playing = not(driver.text[:4] == driver.text[-4:])
[编辑] 根据 Jose 的评论,此信息也可以通过以下方式访问:
driver.find_element_by_class_name("ytp-time-current").text
并发症和下一个问题
我需要以最大化格式打开视频,并自动播放。
这意味着我调用以下 url:
youtube.com/v/<video_code>?rel=0&autoplay=1
但是这个 returns 非常短 html 只包含一个嵌入代码,如这里的示例所示:
<HTML><HEAD></HEAD>
<BODY leftMargin=0 scroll=no topMargin=0>
<EMBED height="100%"
type=application/x-shockwave-flash
width="100%"
src=https://www.youtube.com/v/Fsc-oT9PsSQ?rel=0&autoplay=1
fullscreen="yes">
</BODY>
</HTML>
所以我这里没有 movie_player
元素。
方法 1 - 我可以从 application/x-shockwave-flash
中提取计时器吗?
方法 2 - 如果我在经典 Youtube 页面中启动 youtube 视频,我如何让 movie_player
最大化自己?
(注意:this answer and this answer 可能包含解决方法 2 的信息,post 如果我让它与 Selenium 一起工作,将会 post)
您可以在 youtube 视频页面的上下文中执行 javascript API:
youtubePlayer = document.getElementById("movie_player");
youtubePlayer.getPlayerState();
所以根据https://developers.google.com/youtube/js_api_reference?csw=1
state == 0
是视频结束时
您可以在循环中添加一个执行程序,每 N 秒检查一次状态。
您还可以使用 Youtube iFrame API 的 'onStateChange' 功能在状态发生变化时进行打印。
function onPlayerStateChange(event) {
console.log(player.getPlayerState()); // 1 = Playing || 2 = Paused || 3 = <<- O ->> || 0 = Finished.
}
您可以将视频的长度和当前播放时间作为文本获取,然后将它们转换为秒。另外,作为一个循环,您可以等到当前时间达到视频的长度。
length_str = driver.find_element_by_class_name("ytp-time-duration").text
current_time_str = driver.find_element_by_class_name("ytp-time-current").text
import re
length = re.findall(r'\d+', length_str) # convert ['2:24'] to ['2', '24']
current_time = re.findall(r'\d+', current_time_str)
length_sec = 60 * int(length[0]) + int(length[1])
current_time_sec = (60 * int(current_time[0]) + int(current_time[1]))
remaining_time = length_sec - current_time_sec
driver.find_element_by_class_name("ytp-time-current").text
它只在屏幕上显示时间和标题时有效。几秒钟后,标题消失,返回值为“”。
还有一个办法。只需添加等待 Replay
按钮:
video_ends = driver.find_element_by_css_selector(".ytp-chrome-controls button[title=Replay]")
在 Chrome 工作。
[编辑:已解决,请参阅问题文本的中途]
关于理解其中播放视频的 Youtube 页面内容的快速问题:
总结
我使用 Selenium 在 Youtube 上播放视频,作为基于浏览器的 GUI 的一部分。
我需要知道视频何时播放完毕,以便 GUI 执行其他操作(例如将本地 HTML 馈送到浏览器)。
代码段和问题
import os, time
from selenium import webdriver
# [...]
chromedriver = 'path_to_chromedriver_binary' # substitute as appropriate
driver = webdriver.Chrome(chromedriver)
youtube_link = 'https://www.youtube.com/watch?v=somevideo'
driver.get(youtube_link)
至此,我可以time.wait()
视频的长度。
但是,我想知道我是否可以通过 Selenium 驱动程序查询 YouTube 页面并在 while 循环中计算剩余播放时间(我不熟悉如何从 youtube 页面提取此信息)
谢谢!
[用解决方案编辑]
硒溶液
感谢 Stanjer,感谢 this answer and this other answer,您可以通过此方法获得 movie_player
状态:
player_status = driver.execute_script("return document.getElementById('movie_player').getPlayerState()")
(别忘了在脚本开头加上"return")
Selenium 替代解决方案
不够优雅但值得指出:
driver.text
returns 表示此字符串格式 '1:00 / 2:00' 中的视频计时器的字符串。因此,您可以通过以下方式检查视频是否播放完毕:
video_is_playing = True
while video_is_playing:
time.sleep(1)
video_is_playing = not(driver.text[:4] == driver.text[-4:])
[编辑] 根据 Jose 的评论,此信息也可以通过以下方式访问:
driver.find_element_by_class_name("ytp-time-current").text
并发症和下一个问题
我需要以最大化格式打开视频,并自动播放。
这意味着我调用以下 url:
youtube.com/v/<video_code>?rel=0&autoplay=1
但是这个 returns 非常短 html 只包含一个嵌入代码,如这里的示例所示:
<HTML><HEAD></HEAD>
<BODY leftMargin=0 scroll=no topMargin=0>
<EMBED height="100%"
type=application/x-shockwave-flash
width="100%"
src=https://www.youtube.com/v/Fsc-oT9PsSQ?rel=0&autoplay=1
fullscreen="yes">
</BODY>
</HTML>
所以我这里没有 movie_player
元素。
方法 1 - 我可以从 application/x-shockwave-flash
中提取计时器吗?
方法 2 - 如果我在经典 Youtube 页面中启动 youtube 视频,我如何让 movie_player
最大化自己?
(注意:this answer and this answer 可能包含解决方法 2 的信息,post 如果我让它与 Selenium 一起工作,将会 post)
您可以在 youtube 视频页面的上下文中执行 javascript API:
youtubePlayer = document.getElementById("movie_player");
youtubePlayer.getPlayerState();
所以根据https://developers.google.com/youtube/js_api_reference?csw=1
state == 0
是视频结束时
您可以在循环中添加一个执行程序,每 N 秒检查一次状态。
您还可以使用 Youtube iFrame API 的 'onStateChange' 功能在状态发生变化时进行打印。
function onPlayerStateChange(event) {
console.log(player.getPlayerState()); // 1 = Playing || 2 = Paused || 3 = <<- O ->> || 0 = Finished.
}
您可以将视频的长度和当前播放时间作为文本获取,然后将它们转换为秒。另外,作为一个循环,您可以等到当前时间达到视频的长度。
length_str = driver.find_element_by_class_name("ytp-time-duration").text
current_time_str = driver.find_element_by_class_name("ytp-time-current").text
import re
length = re.findall(r'\d+', length_str) # convert ['2:24'] to ['2', '24']
current_time = re.findall(r'\d+', current_time_str)
length_sec = 60 * int(length[0]) + int(length[1])
current_time_sec = (60 * int(current_time[0]) + int(current_time[1]))
remaining_time = length_sec - current_time_sec
driver.find_element_by_class_name("ytp-time-current").text
它只在屏幕上显示时间和标题时有效。几秒钟后,标题消失,返回值为“”。
还有一个办法。只需添加等待 Replay
按钮:
video_ends = driver.find_element_by_css_selector(".ytp-chrome-controls button[title=Replay]")
在 Chrome 工作。