15

我想获取特定频道的所有视频网址。我认为 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
4

6 回答 6

18

youtube API 更改后,max k. 的答案不起作用。作为替代,下面的函数提供给定频道中的 youtube 视频列表。请注意,您需要一个API 密钥才能使其工作。

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
于 2017-07-02T13:02:27.767 回答
12

将 max-results 从 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
于 2013-03-19T23:16:55.643 回答
6

根据此处和其他一些地方的代码,我编写了一个小脚本来执行此操作。我的脚本使用了 Youtube 的 API v3,并且没有达到 Google 为搜索设置的 500 个结果限制。

该代码可在 GitHub 上获得:https ://github.com/dsebastien/youtubeChannelVideosFinder

于 2014-06-16T04:57:20.930 回答
5

简短的回答:

这是一个可以提供帮助的库。

pip install scrapetube

import scrapetube

videos = scrapetube.get_channel("UC9-y-6csu5WGm29I7JiwpnA")

for video in videos:
    print(video['videoId'])

长答案:

由于缺乏任何其他解决方案,上述模块是由我创建的。这是我尝试过的:

  1. 硒。它有效,但有三大缺点: 1. 它需要安装网络浏览器和驱动程序。2. 对 CPU 和内存有很大的要求。3.不能处理大频道。
  2. 使用 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 来获取所有视频的库。

于 2021-06-25T09:15:59.403 回答
4

独立的做事方式。没有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

上面的代码将仅废弃有限数量的视频 url,最多 60 个。如何抓取频道中存在的所有视频 url。你能建议一下吗?

上面的代码片段将仅显示列出两次的所有视频的列表。并非频道中的所有视频网址。

于 2018-08-22T11:45:34.443 回答
0

使用 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 多个视频的频道存在问题。

于 2020-11-10T21:43:11.937 回答