我是这里的新手。我尝试了很多脚本来执行以下操作。
我的目标是,
我已经拥有 API 密钥,并尝试了我所能做的几乎所有事情来实现这一目标。但是,我无法让它工作。
有人可以告诉我如何完成这项工作吗?
这是一个 Google Apps 脚本,在 Google Sheet 上执行所描述的技巧:
// This Google Apps Script fills a Google Sheet with statistics associated to given YouTube channels.
// More precisely this script assumes that in columns A after the first row there are channel identifiers,
// which can be a channel ID (such as `UC0aMPje3ZACnQPKM_qzY0vw`) or any channel URL such as:
// - https://www.youtube.com/channel/UCK_cUZLMpibyRiIdp0uF-lQ
// - https://www.youtube.com/user/Fairphone
// - https://www.youtube.com/c/lemondefr
function fills_statistics_associated_to_given_youtube_channels() {
const A = 1, B = 2, C = 3, D = 4;
var sheet = SpreadsheetApp.getActiveSheet();
const YOUTUBE_CHANNELS = YouTube.Channels;
const CHANNEL_URL_PREFIX = "https://www.youtube.com/";
// Consider an arbitrary number of channels written after the first row.
for(var row = 2; row <= sheet.getLastRow(); row++)
{
const channelURL = sheet.getRange(row, A).getValue().toString().replace(CHANNEL_URL_PREFIX, "");
// Retrieve the channel ID from the channel identifier provided.
// If the channel URL provided is an username-based one, obtain the associated channel ID.
var channelID;
if(channelURL.startsWith("user/"))
channelID = YOUTUBE_CHANNELS.list("id", {"forUsername": channelURL.replace("user/", "")}).items[0].id;
// As YouTube Data API v3 Channels: list `forUsername` filter doesn't work for this kind of URL, proceed with a YouTube UI reverse-engineering approach.
// This approach consists in obtaining JSON encoded JavaScript `ytInitialData` from the HTML code of the YouTube UI channel.
else if(channelURL.startsWith("c/"))
{
// Note that the following reverse-engineering method isn't working currently because of escaped JSON syntax and I haven't found any clean way to parse it correctly.
/*
const channelHTML = UrlFetchApp.fetch(CHANNEL_URL_PREFIX + channelURL).getContentText();
const ytInitialDataStr = channelHTML.split('">var ytInitialData = ', 2)[1].split(";</script>", 1)[0];
const ytInitialDataJSON = JSON.parse(ytInitialDataStr);
channelID = ytInitialDataJSON["responseContext"]["serviceTrackingParams"][0]["params"][6]["value"];
continue;
*/
// However by relying on a YouTube operational API instance doing this reverse-engineering method, it works fine. Nevertheless if YouTube servers detect the instance as suspicious, you have to host your own instance cf below. If you go this way, replace `yt.lemnoslife.com` to your instance hostname.
// YouTube operational API source code is available at: https://github.com/Benjamin-Loison/YouTube-operational-API
const channelStr = UrlFetchApp.fetch("https://yt.lemnoslife.com/channels?part=snippet&cId=" + channelURL.replace("c/", "")).getContentText();
const channelJSON = JSON.parse(channelStr);
channelID = channelJSON["items"][0]["id"];
}
// Not filtering with `if(channelURL.startsWith("channel/"))` in order to support channel ID too.
else
channelID = channelURL.replace("channel/", "");
// For more details see YouTube Data API v3 Channels: list endpoint documentation: https://developers.google.com/youtube/v3/docs/channels/list
// Note that the channel ID retrieval can't be optimized in terms of HTTPS requests.
// However could optimize the other HTTPS requests to YouTube Data API v3 by implementing using `id` filter to provide up to 50 channel IDs as documented by `maxResults`.
const statistics = YOUTUBE_CHANNELS.list("statistics", {"id": channelID}).items[0].statistics;
sheet.getRange(row, B).setValue(statistics.subscriberCount);
sheet.getRange(row, C).setValue(statistics.viewCount);
sheet.getRange(row, D).setValue(statistics.videoCount);
}
}
请注意,目前的情况
channelURL.startsWith("c/")
依赖于我的开源YouTube操作API。
请注意,此代码不支持句柄,即使 可以支持它们。
试试这个
function myFunction() {
let sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
let range = sheet.getRange(2,1, sheet.getLastRow()-1);
let values = range.getValues();
let mapValues = values.map(function(sr){return sr[0];}).join(",");
let results = YouTube.Channels.list("statistics, contentDetails",{id: mapValues});
let modifyResults = results.items.map(function(sr){return [sr.statistics.subscriberCount, sr.statistics.videoCount, sr.statistics.viewCount]});
sheet.getRange(2,2, modifyResults.length,modifyResults[0].length).setValues(modifyResults);
}