使用 YouTube API 从带有 JSON 提要的视频中获取所有评论

Posted

技术标签:

【中文标题】使用 YouTube API 从带有 JSON 提要的视频中获取所有评论【英文标题】:Using YouTube API to get all comments from a video with the JSON feed 【发布时间】:2012-06-12 02:20:03 【问题描述】:

我正在使用 YouTube API 获取带有参数化查询的视频的 cmets,如下所示:

http://gdata.youtube.com/feeds/api/videos/theVideoID/comments?v=2&alt=json

这样做的问题是每次查询可以获得的最大结果数是 50。我想获得每条评论。我目前正在使用start-indexmax-results 参数来解决这个问题。一次进行 50 次迭代时我遇到了一些麻烦,因为有时迭代的起始索引会高于 cmets 的数量,而我无法弄清楚,所以我只是尝试一次计算一个。一次做 50 个可能会更好,所以让我知道这是否是更好的解决方案。现在:

我正在使用 php 来获取 cmets 的数量:

<?php
    $video_ID = 'gT2HYxOdxUk';
    $JSON = file_get_contents("https://gdata.youtube.com/feeds/api/videos/$video_ID?v=2&alt=json");
    $JSON_Data = json_decode($JSON);
    $commentCount = $JSON_Data->'entry'->'gd$comments'->'gd$feedLink'->'countHint';
?>

然后我调用一个 javascript/jQuery 函数将所有 cmets 加载到一个数组中。为了进行测试,它将它们打印到一个 div 中。对于初学者,这是我调用函数的方式:

<body onLoad="loadComments('<?php echo $commentCount; ?>', '<?php echo $video_ID; ?>')">

接下来,实际功能:

function loadComments(count, videoID)      
    for(i = 1; i <= count; i++) 
        $.ajax(
            url: "http://gdata.youtube.com/feeds/api/videos/" + videoID + "/comments?v=2&alt=json&max-results=1" + "&start-index=" + i,
            dataType: "jsonp",
            success: function(data)
                $.each(data.feed.entry, function(key, val) 
                    comments.push(val.content.$t);
                    $('#commentOutput').append(val.content.$t + '<br>'); //Just for testing purposes.
                );
            

        );
    

问题是它真的很不确定。当我像这样使用 count 变量作为 for 循环的终止部分时,它总是会像这样,例如,211 个 cmets 中有 45 个。如果我手动输入 211,它将达到 195 左右。如果我输入一个较低的数字,比如 1-15,它几乎总是会得到它们。 20+,永远不对。

我需要弄清楚如何通过利用 max-resultsstart-index 参数来始终如一地获取给定视频的所有 cmets。谢谢!

【问题讨论】:

【参考方案1】:

我刚遇到这个问题,我注意到这个问题被问到已经有一段时间了。但既然还没有人回答,我想我应该这样做。

理想情况下,您应该使用 Youtube 的 PHP API(使用 Zend_GData)并在 PHP 中使用以下代码:

<?php

    require_once 'Zend/Loader.php'; // the Zend dir must be in your include_path
Zend_Loader::loadClass('Zend_Gdata_YouTube');

$yt = new Zend_Gdata_YouTube();
$yt->setMajorProtocolVersion(2);
$video = parse_url("http://www.youtube.com/watch?v=K-ob8sr9ZX0");
parse_str(urldecode($video['query']), $query);
$videoId = $query['v'];

$commentFeed = $yt->retrieveAllEntriesForFeed($yt->getVideoCommentFeed($videoId));

foreach ($commentFeed as $commentEntry) 
    echo "Full text: " . $commentEntry->content->text . "<br />";

这里的关键元素是 retrieveAllEntriesForFeed() 方法。

您可以构造一个 JSON 并将其发送回等待的 Javascript,而不是回显所有 cmets。

它不使用 max-resultsstart-index,但没有它们也能很好地完成工作。

【讨论】:

尚未对此进行测试,但我想我可能发现它很有用。正如你所说,我通过使用max-resultsstart-index 参数做了一个小循环,它工作正常。这花了一些时间,我不得不在一定程度上切断它,因为如果它试图循环太多次,它会使我的浏览器崩溃。我会将其添加为答案,因为对于遇到此问题的任何人来说,它似乎更加即时。 如果您发布解决方案会很棒,社区将从中受益,请考虑回馈社区。谢谢! 因为我不清楚,这段代码是否返回所有的 cmets(甚至千)?谢谢!【参考方案2】:

使用 api 的 'orderby' 参数并将其设置为 'published' 以检索几乎所有的 cmets。

https://gdata.youtube.com/feeds/api/videos/<videoID>/comments?max-results=50&alt=json&orderby=published

您仍然可以使用 start-index 参数循环访问 cmets,但这不是一个好主意。

来自文档: API 响应使用标签来识别供稿中上一页和/或下一页条目的分页链接。为避免分页问题,​​我们建议您使用这些链接让用户能够链接到 API 结果的不同页面。

如果提要包含上一页结果,API 响应将包含一个 rel 属性值为 previous 的标签。 如果提要包含下一页结果,则 API 响应将包含一个 rel 属性值为 next 的标签。

https://developers.google.com/youtube/2.0/reference#Paging_through_Results

这样您就不会得到任何嵌套的提要。要获得下一组结果,只需使用上一页结果中给出的链接!希望这可以帮助。它对我有用!

【讨论】:

以上是关于使用 YouTube API 从带有 JSON 提要的视频中获取所有评论的主要内容,如果未能解决你的问题,请参考以下文章

循环多个 JSON 请求(YouTube 数据 API)

带有类别的 Youtube api

如何使用 python 从 youtube v3 api 修复 json?

尝试使用 youtube api 从 json 中提取视频 ID

使用 JSON 从 Youtube API 返回视频时长

从 YouTube API 解析 JSON