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

时间:2020-12-31 18:57:22

I'm using the YouTube API to get comments for a video with a parameterized query like the following:

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

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

The problem with this is that the maximum number of results you can get per query is 50. I want to get every comment. I'm currently using the start-index and max-results parameters to solve this. I had a bit of trouble doing iterations of 50 at a time because sometimes the iteration would have a start-index above the number of comments and I couldn't figure that out, so I just tried to work out one at a time. It may be better to do 50 at a time, so let me know if that is the better solution. For now:

这个问题是每个查询可以得到的最大结果数是50.我想得到每条评论。我目前正在使用start-index和max-results参数来解决这个问题。我一次做50次迭代时遇到了一些麻烦,因为有时候迭代会有一个高于注释数量的start-index而且我无法弄清楚,所以我只想尝试一次一个。最好一次做50个,所以让我知道这是否是更好的解决方案。目前:

I'm using PHP to get the amount of comments:

我正在使用PHP来获取评论量:

<?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'};
?>

And then I'm calling a JavaScript/jQuery function to load all comments into an array. For testing, it prints them into a div. For starters, here's how I'm calling the function:

然后我调用JavaScript / jQuery函数将所有注释加载到数组中。为了测试,它将它们打印成div。对于初学者来说,这就是我如何调用该函数:

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

Next, the actual function:

接下来,实际功能:

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.
                });
            }

        });
    }
}

The problem is that it is really iffy. When I use the count variable as the terminating part of the for loop like this, it always gets like, for example, 45 out of 211 comments. If I manually enter 211, it will go to around 195. If I put in a low number, like 1-15, it pretty much always gets them all. 20+, it's never right.

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

I need to figure out how to get this to consistently get all the comments of a given video by taking advantage of the max-results and start-index parameters. Thanks!

我需要弄清楚如何通过利用max-results和start-index参数来持续获取给定视频的所有注释。谢谢!

2 个解决方案

#1


4  

I just came across this question and I notice that its been quite some time when this was asked. But since nobody answered it yet, I think I should do that.

我刚刚遇到这个问题而且我注意到它被问到这已经很久了。但既然没有人回答,我想我应该这样做。

What you should ideally do is, use Youtube's PHP API (using Zend_GData) and use the following code in PHP:

理想情况下,使用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 />";
}

The key element here is the retrieveAllEntriesForFeed() method.

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

Instead of echo-ing all the comments, you can construct a JSON and send it back to the waiting Javascript.

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

It does not use the max-results or start-index, but does the job well without them.

它不使用max-results或start-index,但没有它们就可以完成工作。

#2


2  

Use the 'orderby' parameter of the api and set it to 'published' to retrieve almost all the comments.

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

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

You can still use the start-index parameter to loop through the comments but it is not a good idea.

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

From the documentation: API responses use tags to identify pagination links for the previous and/or next page of entries in a feed. To avoid pagination problems, we recommend that you use these links to enable users to link to different pages of API results.

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

If a feed contains a previous page of results, the API response will contain a tag with a rel attribute value of previous. If a feed contains a next page of results, the API response will contain a tag with a rel attribute value of next.

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

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

This way you won't get any nested feeds. To get the next set of results simply use the link given on the previous page of results! Hope this helps. It worked for me!

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

#1


4  

I just came across this question and I notice that its been quite some time when this was asked. But since nobody answered it yet, I think I should do that.

我刚刚遇到这个问题而且我注意到它被问到这已经很久了。但既然没有人回答,我想我应该这样做。

What you should ideally do is, use Youtube's PHP API (using Zend_GData) and use the following code in PHP:

理想情况下,使用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 />";
}

The key element here is the retrieveAllEntriesForFeed() method.

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

Instead of echo-ing all the comments, you can construct a JSON and send it back to the waiting Javascript.

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

It does not use the max-results or start-index, but does the job well without them.

它不使用max-results或start-index,但没有它们就可以完成工作。

#2


2  

Use the 'orderby' parameter of the api and set it to 'published' to retrieve almost all the comments.

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

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

You can still use the start-index parameter to loop through the comments but it is not a good idea.

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

From the documentation: API responses use tags to identify pagination links for the previous and/or next page of entries in a feed. To avoid pagination problems, we recommend that you use these links to enable users to link to different pages of API results.

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

If a feed contains a previous page of results, the API response will contain a tag with a rel attribute value of previous. If a feed contains a next page of results, the API response will contain a tag with a rel attribute value of next.

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

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

This way you won't get any nested feeds. To get the next set of results simply use the link given on the previous page of results! Hope this helps. It worked for me!

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