python:获取频道的所有 youtube 视频网址
Posted
技术标签:
【中文标题】python:获取频道的所有 youtube 视频网址【英文标题】:python: get all youtube video urls of a channel 【发布时间】:2013-03-08 21:07:07 【问题描述】:我想获取特定频道的所有视频网址。我认为 json 与 python 或 java 将是一个不错的选择。我可以使用以下代码获取最新视频,但是如何获取所有视频链接 (>500)?
import urllib, json
author = 'Youtube_Username'
inp = urllib.urlopen(r'http://gdata.youtube.com/feeds/api/videos?max-results=1&alt=json&orderby=published&author=' + author)
resp = json.load(inp)
inp.close()
first = resp['feed']['entry'][0]
print first['title'] # video title
print first['link'][0]['href'] #url
【问题讨论】:
【参考方案1】:在 youtube API 更改后,max k. 的答案不起作用。作为替代,下面的函数提供给定频道中的 youtube 视频列表。请注意,您需要API Key 才能使用它。
import urllib
import json
def get_all_video_in_channel(channel_id):
api_key = YOUR API KEY
base_video_url = 'https://www.youtube.com/watch?v='
base_search_url = 'https://www.googleapis.com/youtube/v3/search?'
first_url = base_search_url+'key=&channelId=&part=snippet,id&order=date&maxResults=25'.format(api_key, channel_id)
video_links = []
url = first_url
while True:
inp = urllib.urlopen(url)
resp = json.load(inp)
for i in resp['items']:
if i['id']['kind'] == "youtube#video":
video_links.append(base_video_url + i['id']['videoId'])
try:
next_page_token = resp['nextPageToken']
url = first_url + '&pageToken='.format(next_page_token)
except:
break
return video_links
【讨论】:
这是一个简单而准确的答案,因为我在 Python API 参考中找不到它。 @Stian 它给出了错误 HTTPError: HTTP Error 403: Forbidden 对于 Python 3:import urllib.request
,将 inp = urllib.urlopen(url)
更改为 inp = urllib.request.urlopen(url,timeout=1)
@smcs 它不起作用。 urllib.error.HTTPError:HTTP 错误 403:禁止
@rtt0012 你应该在codereview.stackexchange.com提出问题【参考方案2】:
将最大结果从 1 增加到您想要的任意数量,但请注意,他们不建议在一次调用中获取太多结果,并且会将您限制为 50 (https://developers.google.com/youtube/2.0/developers_guide_protocol_api_query_parameters)。
相反,您可以考虑以 25 个为一组来抓取数据,例如,通过更改 start-index 直到没有返回。
编辑:这是我将如何做的代码
import urllib, json
author = 'Youtube_Username'
foundAll = False
ind = 1
videos = []
while not foundAll:
inp = urllib.urlopen(r'http://gdata.youtube.com/feeds/api/videos?start-index=0&max-results=50&alt=json&orderby=published&author=1'.format( ind, author ) )
try:
resp = json.load(inp)
inp.close()
returnedVideos = resp['feed']['entry']
for video in returnedVideos:
videos.append( video )
ind += 50
print len( videos )
if ( len( returnedVideos ) < 50 ):
foundAll = True
except:
#catch the case where the number of videos in the channel is a multiple of 50
print "error"
foundAll = True
for video in videos:
print video['title'] # video title
print video['link'][0]['href'] #url
【讨论】:
很好的答案,但最好使用“except SpecificError”之类的东西,而不是通用异常:如果 json 加载或响应解析有其他问题,这种代码将隐藏他们。 好点子,如果发帖者决定使用它,那么做一些研究并找出具体错误绝对是个好主意 如果你要删除:print len(video) 那么你会得到错误......所以我认为需要修复它。 @CatalinFestila 在我的情况下这不是真的。我可以删除每个打印件(包括 len(videos)),它会起作用。检查其他事项,然后重试。 根据此回复youtube.com/devicesupport,我认为现在已弃用此功能【参考方案3】:根据此处和其他一些地方的代码,我编写了一个小脚本来执行此操作。我的脚本使用了 Youtube 的 API v3,并且没有达到 Google 为搜索设置的 500 个结果限制。
代码可在 GitHub 上获得:https://github.com/dsebastien/youtubeChannelVideosFinder
【讨论】:
谢谢。结合pafy,您可以获取频道上的所有视频。 这不适用于 PyCon 2015 频道,甚至 git 上提到的示例,它只是说找不到频道。我是不是做错了什么。 我在使用它时遇到了很多错误。诚然,我的频道名称中似乎有一个空格,这在 cli 上造成了麻烦,但该工具没有取而代之的是 ID,但它搜索了 5 年并没有找到 vidz,我在频道上有 410 . 仅供参考,我没有时间维护该项目,但如果有人感兴趣,请不要犹豫去修复它,我会很乐意合并任何改进 ;-)【参考方案4】:简答:
这是一个可以帮助解决这个问题的库。
pip install scrapetube
import scrapetube
videos = scrapetube.get_channel("UC9-y-6csu5WGm29I7JiwpnA")
for video in videos:
print(video['videoId'])
长答案:
由于缺乏任何其他解决方案,上述模块是我创建的。这是我尝试过的:
-
硒。它有效,但有三大缺点: 1. 它需要安装网络浏览器和驱动程序。 2. 对 CPU 和内存有很大的要求。 3. 无法处理大频道。
使用 youtube-dl。像这样:
import youtube_dl
youtube_dl_options =
'skip_download': True,
'ignoreerrors': True
with youtube_dl.YoutubeDL(youtube_dl_options) as ydl:
videos = ydl.extract_info(f'https://www.youtube.com/channel/channel_id/videos')
这也适用于小型频道,但对于较大的频道,我会因为在这么短的时间内发出如此多的请求而被 youtube 阻止(因为 youtube-dl 会为频道中的每个视频下载更多信息)。
所以我创建了库 scrapetube
,它使用 Web API 来获取所有视频。
【讨论】:
非常好的解决方案,另外,如果有人要获取视频 url 代替 id,您可以使用print("https://www.youtube.com/watch?v="+str(video['videoId']))
代替 print(video['videoId'])
。【参考方案5】:
独立的做事方式。没有api,没有速率限制。
import requests
username = "marquesbrownlee"
url = "https://www.youtube.com/user/username/videos"
page = requests.get(url).content
data = str(page).split(' ')
item = 'href="/watch?'
vids = [line.replace('href="', 'youtube.com') for line in data if item in line] # list of all videos listed twice
print(vids[0]) # index the latest video
上面的代码将仅废弃有限数量的视频网址,最多 60 个。如何抓取频道中存在的所有视频网址。能否请教一下。
上面的代码 sn-p 将仅显示列出两次的所有视频的列表。并非频道中的所有视频网址。
【讨论】:
【参考方案6】:使用 Selenium Chrome 驱动程序:
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
import time
driverPath = ChromeDriverManager().install()
driver = webdriver.Chrome(driverPath)
url = 'https://www.youtube.com/howitshouldhaveended/videos'
driver.get(url)
height = driver.execute_script("return document.documentElement.scrollHeight")
previousHeight = -1
while previousHeight < height:
previousHeight = height
driver.execute_script(f'window.scrollTo(0,height + 10000)')
time.sleep(1)
height = driver.execute_script("return document.documentElement.scrollHeight")
vidElements = driver.find_elements_by_id('thumbnail')
vid_urls = []
for v in vidElements:
vid_urls.append(v.get_attribute('href'))
这段代码在我尝试过几次后都有效;但是,您可能需要调整睡眠时间,或者添加一种方法来识别浏览器何时仍在加载额外信息。它很容易让我获得一个包含 300 多个视频的频道,但是由于在浏览器上加载新视频所需的时间变得不一致,它在拥有 7000 多个视频的频道上遇到了问题。
【讨论】:
以上是关于python:获取频道的所有 youtube 视频网址的主要内容,如果未能解决你的问题,请参考以下文章
获取 youtube 频道上所有上传视频的带有 id 的 XML