0

我已经在网上搜索了好几天,只是寻找一个使用 C# API 的 YouTube 批处理请求的工作示例,但没有成功。很多文档已经过时了。

这些告诉我 XML 应该是什么样子:

https://developers.google.com/gdata/docs/batch https://developers.google.com/youtube/2.0/developers_guide_protocol_batch_processing

这是谷歌电子表格的一个例子:

https://developers.google.com/google-apps/spreadsheets/#updating_multiple_cells_with_a_batch_request

虽然我一次又一次地非常接近,但我一直未能达到描述性 GDataRequestException “执行请求批处理失败”的目标。

帮助!

4

1 回答 1

1

终于破解了!

现在,所以你不必经历我所经历的同样的盲目试验和恐怖经历:

using Google.GData.Client;
using Google.GData.YouTube;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
...
YouTubeService service = new YouTubeService("YouTube API Client", Properties.Settings.Default.YouTubeDeveloperKey);
const String searchFields = "entry(id,title,link[@rel='alternate'],author(name,yt:userId),media:group(media:category(@label),media:credit,yt:videoid,yt:uploaderId),yt:statistics,yt:rating,gd:rating(@average),gd:comments/gd:feedLink(@countHint))";
String urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/videos", (testing ? "stage." : "")); 
String url = String.Format("{0}?v=2&fields={1}", urlBase, searchFields);
Debug.Print(url);
YouTubeQuery searchQuery = new YouTubeQuery(url);
searchQuery.Query = keyword;
searchQuery.NumberToRetrieve = Properties.Settings.Default.NumVideosToRetrieve;
searchQuery.OrderBy = "relevance";
lblTagStats.Text = "Retrieving Top " + searchQuery.NumberToRetrieve + " Videos...";
YouTubeFeed searchResults = service.Query(searchQuery);
DebugSaveToXml(searchResults, "searchResults");
foreach (YouTubeEntry entry in searchResults.Entries)
{
    titles.Add(entry.Title.Text);
    if (entry.Statistics != null)
        viewCounts.Add(long.Parse(entry.Statistics.ViewCount));
    if (entry.Comments != null)
        commentCounts.Add(long.Parse(entry.Comments.FeedLink.CountHint.ToString()));
    if (entry.Rating != null)
        ratings.Add(entry.Rating.Average);
    if (entry.YtRating != null)
    {
        likeCounts.Add(long.Parse(entry.YtRating.NumLikes));
        dislikeCounts.Add(long.Parse(entry.YtRating.NumDislikes));
    }
    videoURLs.Add(new Uri(entry.AlternateUri.ToString()));
    uploaders.Add(entry.Authors[0].Name);
    foreach (var category in entry.Media.Categories)
        if (category.Attributes["label"] != null)
            categories.Add(category.Attributes["label"].ToString());
}

lblTagStats.Text = "Retrieving Subscriber Counts...";
AtomFeed batchRequest = new AtomFeed(searchResults);
batchRequest.BatchData = new GDataBatchFeedData();
batchRequest.BatchData.Type = GDataBatchOperationType.query;
foreach (YouTubeEntry entry in searchResults.Entries)
{
    AtomEntry batchEntry = searchResults.CreateFeedEntry();
    String uploaderId = entry.Media.ChildNodes.Find(x => x.Name == "yt:uploaderId").InnerText;
    batchEntry.Id = new AtomId("tag:youtube.com,2008:user:" + uploaderId);  //not returned in search, so reconstruct it
    batchEntry.BatchData = new GDataBatchEntryData();
    urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/users", (testing ? "stage." : ""));
    url = String.Format("{0}/{1}?v=2", urlBase, entry.Media.Credit.Value);
    Debug.Print(url);
    batchEntry.EditUri = url;
    batchRequest.Entries.Add(batchEntry);
}
DebugSaveToXml(batchRequest, "batchRequest_Profiles");

const String profileFields = ""; // "&fields=id,yt:username,yt:statistics(@subscriberCount)"; // YouTube API bug: cant handle colons in batch request fields
urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/users/batch", (testing ? "stage." : ""));
url = String.Format("{0}?v=2{1}", urlBase, profileFields);
Debug.Print(url);
YouTubeFeed profilesFeed = (YouTubeFeed)service.Batch(batchRequest, new Uri(url));
DebugSaveToXml(profilesFeed,"profilesFeed");
foreach (ProfileEntry entry in profilesFeed.Entries)
    if (entry.BatchData.Status.Code == 200)
        subscriberCounts.Add(long.Parse(entry.Statistics.SubscriberCount));



lblTagStats.Text = "Retrieving Full Descriptions...";
batchRequest = new AtomFeed(searchResults);
batchRequest.BatchData = new GDataBatchFeedData();
batchRequest.BatchData.Type = GDataBatchOperationType.query;
foreach (YouTubeEntry entry in searchResults.Entries)
{
    AtomEntry batchEntry = searchResults.CreateFeedEntry();
    batchEntry.Id = entry.Id;
    batchEntry.BatchData = new GDataBatchEntryData();
    urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/videos", (testing ? "stage." : ""));
    url = String.Format("{0}/{1}?v=2", urlBase, entry.VideoId);
    Debug.Print(url);
    batchEntry.EditUri = url;
    batchRequest.Entries.Add(batchEntry);
}
DebugSaveToXml(batchRequest, "batchRequest_Descriptions");

const String descriptionFields = ""; // "&fields=media:group/media:description"; // YouTube API bug: cant handle colons in batch request fields
urlBase = String.Format("https://{0}gdata.youtube.com/feeds/api/videos/batch", (testing ? "stage.":""));
url = String.Format("{0}?v=2{1}", urlBase, descriptionFields);
Debug.Print(url);
YouTubeFeed descriptionsFeed = (YouTubeFeed)service.Batch(batchRequest, new Uri(url));
DebugSaveToXml(descriptionsFeed,"descriptionsFeed");

foreach (YouTubeEntry entry in descriptionsFeed.Entries)
    if (entry.BatchData.Status.Code == 200)
        descriptions.Add(entry.Media.Description.Value);

仅供参考,这为配置文件发布了以下批处理请求 XML,这与其他示例有很大不同,但仍然像魅力一样工作:

<feed xmlns="http://www.w3.org/2005/Atom" xmlns:batch="http://schemas.google.com/gdata/batch">
  <link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" />
  <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" />
  <link rel="self" type="application/atom+xml" />
  <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" />
  <batch:operation type="query" />
  <entry xmlns:gd="http://schemas.google.com/g/2005">
    <id>tag:youtube.com,2008:user:UC7UgD2HIyslGofSyX811fsQ</id>
    <link href="https://stage.gdata.youtube.com/feeds/api/users/inspiredtennis?v=2" rel="edit" type="application/atom+xml" />
  </entry>
  <entry xmlns:gd="http://schemas.google.com/g/2005">
    <id>tag:youtube.com,2008:user:UClXdxsQW4AqykIq2Fu4YXvQ</id>
    <link href="https://stage.gdata.youtube.com/feeds/api/users/azishertanto?v=2" rel="edit" type="application/atom+xml" />
  </entry>
  <entry xmlns:gd="http://schemas.google.com/g/2005">
    <id>tag:youtube.com,2008:user:UC1Diq4duvGuTUaGxk61-LOQ</id>
    <link href="https://stage.gdata.youtube.com/feeds/api/users/atamaiidotcom?v=2" rel="edit" type="application/atom+xml" />
  </entry>
  ...
</feed>
于 2013-04-13T06:05:11.793 回答