我正在使用 youtube v3 API 检索播放列表的视频并获得 50 个项目,而此链接没有任何问题:-
但是视频数是 100,而我只有 50 个。我怎样才能获得接下来的 50 个项目?我尝试了start-index但它不适用于 v3 API。任何帮助表示赞赏。
我正在使用 youtube v3 API 检索播放列表的视频并获得 50 个项目,而此链接没有任何问题:-
但是视频数是 100,而我只有 50 个。我怎样才能获得接下来的 50 个项目?我尝试了start-index但它不适用于 v3 API。任何帮助表示赞赏。
YouTube Data API v3 结果是分页的。因此,您需要为其他人获取下一页结果。
基本上在响应中你有nextPageToken。
要获得剩余的结果,请执行相同的调用,但将pageToken设置为您收到的令牌。
有三个令牌
你也可以使用设置最大页面大小
maxResults=50 {允许的值 1 到 50 }
如果你在第 1 页,你不会得到prevPageToken
但你得到nextPageToken
将此令牌传递给下一个请求
pageToken = {nextPageToken 从上次请求中获取}
这样你就可以导航到下一页自己试试
好的,对于其他场景
如果您在首页,那么
如果您既不在第一页也不在最后一页,那么
@Manoj:你可以在下面找到你的答案
如果你在最后一页
甚至该字段也可能不存在。
这是一个使用 Python Youtube Client Lib 在 python 中制作的小例子这也从 youtube API 示例中借用了样板设置
""" Pull All Youtube Videos from a Playlist """
from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.tools import argparser
DEVELOPER_KEY = "YOURKEY HERE"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
def fetch_all_youtube_videos(playlistId):
"""
Fetches a playlist of videos from youtube
We splice the results together in no particular order
Parameters:
parm1 - (string) playlistId
Returns:
playListItem Dict
"""
youtube = build(YOUTUBE_API_SERVICE_NAME,
YOUTUBE_API_VERSION,
developerKey=DEVELOPER_KEY)
res = youtube.playlistItems().list(
part="snippet",
playlistId=playlistId,
maxResults="50"
).execute()
nextPageToken = res.get('nextPageToken')
while ('nextPageToken' in res):
nextPage = youtube.playlistItems().list(
part="snippet",
playlistId=playlistId,
maxResults="50",
pageToken=nextPageToken
).execute()
res['items'] = res['items'] + nextPage['items']
if 'nextPageToken' not in nextPage:
res.pop('nextPageToken', None)
else:
nextPageToken = nextPage['nextPageToken']
return res
if __name__ == '__main__':
# comedy central playlist, has 332 video
# https://www.youtube.com/watch?v=tJDLdxYKh3k&list=PLD7nPL1U-R5rDpeH95XsK0qwJHLTS3tNT
videos = fetch_all_youtube_videos("PLD7nPL1U-R5rDpeH95XsK0qwJHLTS3tNT")
视频将是连接到第一个列表的所有视频的列表。由于分页数为 50,它将继续获取直到拥有所有视频。类似的方法可以在其他语言中采用。
在列表中将有所有单独的视频元数据和顺序
在 youtube 发送给我们的 JSON 数据中,data.pageInfo.totalResults 只是原始的视频总数。几个月或几年后,这个数字可能会因为视频删除、禁止而减少……实际上 youtube 只为我们提供当前可播放的视频。因此,我们需要更改代码以获得更好的代码。
我们不应该使用 if(sum == data.pageInfo.toTalResults) 作为停止条件。相反,让我们使用标准 if(typeof nextPageToken == 'undefined')。
在当前总数小于原始总数的情况下。如果我们使用旧编码,那么最后一个函数调用是使用未定义的 nextPageToken 进行的。这导致 Youtube 再次错误地给了我们第一个 JSON 页面。在结果中,我们有一些重复的视频。
请尝试我的新编码(看起来像 user3053204 先生给出的编码)
/* new coding. Please replace and use your api3 key */
function start(){
count = 0;
$('#area1').val('');
getVids();
}
function getVids(PageToken){
pid = $('#searchtext1').val();
$.get(
"https://www.googleapis.com/youtube/v3/playlistItems",{
part : 'snippet',
maxResults : 50,
playlistId : pid,
pageToken : PageToken,
key: 'AIz....................................zm4'
},
function(data){
myPlan(data);
}
);
}
count = 0;
str = '';
function myPlan(data){
nextPageToken=data.nextPageToken;
pageLen = data.items.length;
count += parseInt(pageLen);
for(i=0; i<pageLen; i++){
str += '"' + data.items[i].snippet.resourceId.videoId + '", ';
}
if(typeof nextPageToken == 'undefined'){
total = data.pageInfo.totalResults;
$('#all').html(count + '/' + total + ' videos');
ind = str.lastIndexOf(',');
str1 = str.substring(0, ind);
$('#area1').val('arr = [' + str1 + '];\n');
return;
}else{
getVids(nextPageToken);
}
}
<input type="text" value="PLTI6yRvQqlYq9KoU-NHu43uDmKON7Fsjv"
id="searchtext1" size="75">
<button onclick="start()">Get Items</button>
<br><br>
IDs for test: <br>
<br>
Ricky King playlist (92/103 videos):<br>
PLTI6yRvQqlYq9KoU-NHu43uDmKON7Fsjv<br>
Franck Pourcel playlist (425/425 videos):<br>
PLMGmDo5xNOgU7gerHMwEk6SmD_vbPyLe9<br>
Lobo playlist (25/41vids):<br>
PLFE095732AC64AD06
<br><br>
TOTAL: <span id="all"></span><br>
<textarea id="area1" style="width:600px;height:500px;;font-size:12pt"></textarea>
/* old coding - to be cleared */
sum = 0;
sumN = 1;
var nextPageToken;
function getVids(PageToken){
pid = $('#searchtext1').val();
$.get(
"https://www.googleapis.com/youtube/v3/playlistItems",{
part : 'snippet',
maxResults : 50,
playlistId : pid,
pageToken : PageToken,
key: 'YOUR API3 KEY'
},
function(data){
myPlan(data);
}
);
}
function myPlan(data){
total = data.pageInfo.totalResults;
nextPageToken=data.nextPageToken;
for(i=0;i<data.items.length;i++){
document.getElementById('area1').value +=
sumN + '-' + data.items[i].snippet.title+'\n'+
data.items[i].snippet.resourceId.videoId +'\n\n';
sum++ ; sumN++;
if(sum == (total-1) ){
sum = 0;
return;
}
}
if(sum <(total-1)){
getVids(nextPageToken);
}
}
function init(){
$('#area1').val('');
}
<!- - old coding - to be cleared - ->
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<body onload="$('#area1').val('')">
<input type="text" value="PLTI6yRvQqlYq9KoU-NHu43uDmKON7Fsjv"
id="searchtext1" size="75">
<button onclick="getVids()">Get Items</button>
<br><br>
IDs for test: <br>PLTI6yRvQqlYq9KoU-NHu43uDmKON7Fsjv<br>
PL32C69B40337EF920
<br><br>
<textarea id="area1" style="width:600px;height:500px">
</textarea>
获取所有视频的最简单方法,
DEVELOPER_KEY = "REPLACE_ME" YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3"
youtube = build("youtube", "v3", developerKey=api_key)
def get_videos_from_playlist(youtube, items, playlistID):
response = items.list(part="snippet", playlistId=playlistID)
while response:
playlistitems_list_response = response.execute()
for playlist_item in playlistitems_list_response["items"]:
# title = playlist_item["snippet"]["title"]
video_id = playlist_item["snippet"]["resourceId"]["videoId"]
yield video_id
response = youtube.playlistItems().list_next(
response, playlistitems_list_response)
传递播放列表 ID,
items = youtube.playlistItems()
playlist = get_videos_from_playlist(youtube, items, 'PLoROMvodv4rOhcuXMZkNm7j3fVwBBY42z')
然后解析列表:
for videoID in playlist:
print(videoID)
此外,您可以使用页面来抓取多个页面,例如:
nextPageToken = res.get('nextPageToken')
while ('nextPageToken' in res):
nextPage = youtube.playlistItems().list(
part="snippet",
playlistId=playlistId,
maxResults="50",
pageToken=nextPageToken
).execute()
res['items'] = res['items'] + nextPage['items']
if 'nextPageToken' not in nextPage:
res.pop('nextPageToken', None)
else:
nextPageToken = nextPage['nextPageToken']
另一种解决方案,使用递归:
$.fn.loadYoutubeResource = function(resource_request, resource_type, resource_id, resource_container, pageToken = null, callback = null){
$.ajax({
url: "https://www.googleapis.com/youtube/v3/" + resource_request,
type: 'get',
dataType: 'json',
data: {
part : 'snippet',
[resource_type]: resource_id,
maxResults : 50,
pageToken: pageToken,
key: '< API Key >',
},
success: function(data) {
console.log("New resource " + resource_type + " loaded:");
console.log(data);
for(var index = 0; index < data.items.length; index++){
var url = data.items[index]['snippet'].thumbnails.default.url;
var ytb_id = data.items[index]['id'];
jQuery('#' + resource_container).append('<img class="tube_thumbs" src="' + url + '" id="' + ytb_id
+ '" title="' + data.items[index]['snippet']['title'] + '" >');
}
if ( data.nextPageToken == null)
return callback();
$.fn.loadYoutubeResource(resource_request, resource_type, resource_id, resource_container, data.nextPageToken, callback);
}
});
}
然后按如下方式调用它:
jQuery('body').append('<div id="ytb_container"></div>');
$.fn.loadYoutubeResource('playlistItems', 'playlistId', 'PLmwK57OwOvYVdedKc_vPPfbcsey_R0K8r', 'ytb_container', null, function(){ <callback code>});
这是我的递归函数,也许可以帮助某人:
首先,我为第一次通话创建了一个按钮:
<button id="aux" class="btn btn-danger">Click Me</button>
然后在脚本部分:
$(document).ready(function () {
function getVideos(t) {
var url = "https://www.googleapis.com/youtube/v3/search?part=snippet&key=YourAPIKey&channelId=YourChannelID&maxResults=50";
if (t != undefined) {
url = url + "&pageToken=" + t
}
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success: function (html) {
console.log(html.items);
if (html.nextPageToken != undefined) {
getVideos(html.nextPageToken);
}
}
});
};
//initial call
$("#aux").click(function () {
getVideos();
});
});
问候
另一种方法(不需要知道请求格式并拥有api密钥):只需使用youtube播放列表html文件中的json并使用JSON.parse方法
不幸的是,这种方法不能提供超过200个视频。在 json 中,我看到了一些关键代码,可能是为了继续,但不能使用它们。
要获取 html 源代码,我们可以使用 jquery $.ajax 方法。
<meta charset = utf-8>
<body>
<div id="help" style="width:90%">
1- Open youtube.com and search for playlist (http://www.youtube.com/....&list=...)<br>
For example: click <a href="http://www.youtube.com/watch?v=sMyj9e2qOc0&list=PL33196EF7664597D5">paul mauriat playlist</a><br>
You will see in the adress bar: http://www.youtube.com/watch?v=sMyj9e2qOc0&list=PL33196EF7664597D5 <br>
Select all and copy this url.<br>
2- Open any online html source code viewer. For example<br>
<a href="https://www.duplichecker.com/page-snooper.php">
https://www.duplichecker.com/page-snooper.php</a><br>
Paste the url, click "Enter", wait several seconds, scroll down, click "Copy"<br>
3- Return to this page. Paste the code to the below input smal textarea, wait several seconds, click "GET VIDEO IDS".<br>
4- Click the button TEST JAVASCRIPT.
</div><br>
<textarea id = "input">
</textarea><br>
<button onclick="extract()">GET VIDEOS IDS</button><br>
Total: <span id='len'></span>
<br><button onclick="test()">TEST JAVASCRIPT</button><br>
COPY THIS TO CREATE A JAVASCRIPT FILE<br>
<textarea id="area2" style="width:90%;height:400px;font-size:14pt">
</textarea><br>
<script>
function extract(){
str = document.getElementById('input').value;
aa = str.indexOf('{"responseContext');
bb = str.indexOf('{"related', aa);
jsn = str.substring(aa, bb + 24);
obje = JSON.parse(jsn);
alert('Click OK to continue');
make();
}
glStr = '';
function make(){
len = obje.contents.singleColumnWatchNextResults.playlist.playlist.contents.length;
ss = '';
for(i=0; i < len; i++){
try{
ti = obje.contents.singleColumnWatchNextResults.playlist.playlist.contents[i].playlistPanelVideoRenderer.title.runs[0].text;
ti1 = ti.replace(/"/g,'\\"');
ide = obje.contents.singleColumnWatchNextResults.playlist.playlist.contents[i].playlistPanelVideoRenderer.navigationEndpoint.watchEndpoint.videoId;
}catch(e){
ide = obje.contents.singleColumnWatchNextResults.playlist.playlist.contents[i].playlistPanelVideoRenderer.videoId;
ti1 = '[Deleted Video]';
}
ss += '{vid:"' + ide + '",tit:"' + ti1 + '"}';
if(i != (len - 1)){
ss += ',\n';
}
}
glStr = 'obj = \n[' + ss + '\n];\n';
document.getElementById('area2').value = glStr;
document.getElementById('len').innerHTML = len + ' videos';
}
function test(){
var head = document.getElementsByTagName('head').item(0);
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.innerHTML = glStr;
head.appendChild(script);
alert('obj.length = ' + obj.length);
alert('obj[5].vid = ' + obj[5].vid + '\n obj[5].tit = ' + obj[5].tit);
}
</script>
</body>
我做了如下,但我不知道这个是优化的,还是不知道我是如何得到我预期的结果的。
说明: 将从播放列表中检索所有视频并动态推送到数组中。
服务中:
getSnippets(token): any {
console.log('API_TOKEN:',token);
if(token){
return this.http.get('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLV_aspERmuCKxUPxu8UwUd3I52VLje0ra&maxResults=100&key=[API_KEY]='+token).toPromise();
}else{
return this.http.get('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=PLV_aspERmuCKxUPxu8UwUd3I52VLje0ra&maxResults=100&key=[API_KEY]').toPromise();
}
}
要显示数据:
async getPlayList(){
try{
let pageToken;
this.finalAr = [];
// for(let t = 0; t <= 1; t++) {
const list = await this.service.getSnippets(pageToken);
pageToken = list.nextPageToken;
// let pageInfo = list.pageInfo;
let pageTot = list.pageInfo.totalResults;
let resultsPerPage = list.pageInfo.resultsPerPage;
let loopCnt = pageTot / resultsPerPage;
let finalCnt = Math.abs(Math.ceil(loopCnt)) - 1 ;
if(pageToken != undefined || pageToken != null){
let tempAr = list.items;
for(let i = 0; i < tempAr.length; i++){
this.finalAr.push({"vid_id" : tempAr[i].snippet.resourceId.videoId,
"vid_title": tempAr[i].snippet.title,
"vid_desc" : tempAr[i].snippet.description,
"vid_icon" : 'https://i.ytimg.com/vi/'+tempAr[i].snippet.resourceId.videoId+'/sddefault.jpg'
})
}
console.log('finalAr_1:',this.finalAr);
}
for(let a = 1; a <= finalCnt; a++){
const listF = await this.service.getSnippets(pageToken);
pageToken = listF.nextPageToken;
let tempAr = listF.items;
for(let i = 0; i < tempAr.length; i++){
this.finalAr.push({"vid_id" : tempAr[i].snippet.resourceId.videoId,
"vid_title": tempAr[i].snippet.title,
"vid_desc" : tempAr[i].snippet.description,
"vid_icon" : 'https://i.ytimg.com/vi/'+tempAr[i].snippet.resourceId.videoId+'/sddefault.jpg'
})
}
console.log('finalAr_2:',this.finalAr);
}
}catch (e){
console.log('ER:',e);
}
做了工作。但是,如果有人知道这件事,我想从多个播放列表中检索所有视频,请告诉我。