YouTube API - 检索超过 5k 项

问题描述 投票:0回答:3

我只想获取所有我喜欢的视频~25k 个项目。据我的研究,这是不可能通过 YouTube v3 API 实现的。

我已经在同一个问题上发现了多个问题(问题问题),尽管有些人声称已经修复了它,但它只适用于他们,因为他们没有< 5000 items in their liked video list.

播放列表 ID 设置为“喜欢的视频”(LL) 的

playlistItems 列表 API 端点限制为 5000

视频列表 API 端点限制为 1000

不幸的是,这些端点没有向我提供可用于对请求进行分页的参数(例如,为我提供日期 x 和 y 之间所有喜欢的视频),因此我被迫接受所提供的订单(我可以这样做)没有超过 5000 个条目)。

我是否可以通过 API 获取我所有的点赞?

youtube-api youtube-data-api
3个回答
3
投票

对@Yarin_007 的回复有更多想法

  • 如果时间线中存在已删除的视频 they appear as ,则脚本不喜欢该格式,并且会失败,因为底层元素与现有视频的结构不同 可以通过 try catch 轻松修复
function collector(all_cards) { 
    var liked_videos = {};
    all_cards.forEach(card => {
        try {
            // ignore Dislikes
            if (card.innerText.split("\n")[1].startsWith("Liked")) {
                ....
            }
        }
        catch {
            console.log("error, prolly deleted video")
        }
    })

    return liked_videos;
}
  • 要向下滚动到页面底部,我使用了这个简单的脚本,无需启动大的东西
var millisecondsToWait = 1000;
setInterval(function() {
    window.scrollTo(0, document.body.scrollHeight);
    console.log("scrolling")
}, millisecondsToWait);
  • 当更多人想要检索此类数据时,可以考虑构建一个更方便使用的合适脚本。 If you check the network requests您可以在称为batchexecute的请求响应中找到所需的数据。人们可以复制其中一个的身份验证,将它们提供给一个脚本,该脚本查询这些端点并准备数据,就像我当前手动注入的另一个脚本一样。

2
投票

嗯。也许是Google Takeout

我已验证 YouTube 数据包含一个名为“likedvideos.csv”的 csv。标题为

Video Id,Time Added
,行为

dQw4w9WgXcQ,2022-12-18 23:42:19 UTC

prvXCuEA1lw,2022-12-24 13:22:13 UTC

例如。

因此您需要检索每个视频 ID 的视频元数据。不过还不错。

注意: 导出可能需要一段时间,尤其是 25k 视频。 (仅选择 YouTube 数据)

我还有一个想法,涉及抓取实际喜欢的视频页面(这将为您节省 25k HTTP 请求)。但我不确定超过 5000 首歌曲是否会崩溃。 (此外,模拟该页面上的 POST 请求可能会相当困难,尽管并非不可能。(它们获取 /browse?key=...,并且在请求正文中具有某种模糊/加密的 base64 字符串以及其他参数) )


编辑:

看。可能有一种正常的方法可以完整转储所有谷歌数据。 (我的意思是,除了外卖。给他们发电子邮件?我不知道。) 无论如何,以下是另一个想法...

  1. 按照此深层链接查看您喜欢的视频历史记录。

  2. 滚动到底部...也许使用selenium,也许使用autoit,也许在键盘的“结束”键上放一些东西,直到到达第一个喜欢的视频。

  3. 按 f12 并在开发者控制台中运行它

// https://www.youtube.com/watch?v=eZPXmCIQW5M
// https://myactivity.google.com/page?utm_source=my-activity&hl=en&page=youtube_likes 



// go over all "cards" in the activity webpage. (after scrolling down to the absolute bottom of it)
// create a dictionary - the key is the Video ID, the value is a list of the video's properties
function collector(all_cards) { 
    var liked_videos = {};
    all_cards.forEach(card => {
        // ignore Dislikes
        if (card.innerText.split("\n")[1].startsWith("Liked")) {
            // horrible parsing. your mileage may vary. I Tried to avoid using any gibberish class names.
            let a_links = card.querySelectorAll("a")
            let details = a_links[0];
            let url = details.href.split("?v=")[1]
            let video_length = a_links[3].innerText;
            let time = a_links[2].parentElement.innerText.split(" • ")[0];
            let title = details.innerText;
            let date = card.closest("[data-date]").getAttribute("data-date")
            liked_videos[url] = [title,video_length, date, time];
            // console.log(title, video_length, date, time, url);
        }
    })

    return liked_videos;
}


// https://stackoverflow.com/questions/57709550/how-to-download-text-from-javascript-variable-on-all-browsers
function download(filename, text, type = "text/plain") {
    // Create an invisible A element
    const a = document.createElement("a");
    a.style.display = "none";
    document.body.appendChild(a);

    // Set the HREF to a Blob representation of the data to be downloaded
    a.href = window.URL.createObjectURL(
        new Blob([text], { type })
    );
    
    // Use download attribute to set set desired file name
    a.setAttribute("download", filename);

    // Trigger the download by simulating click
    a.click();

    // Cleanup
    window.URL.revokeObjectURL(a.href);
    document.body.removeChild(a);
}

function main() {
    // gather relevant elements
    var all_cards = document.querySelectorAll("div[aria-label='Card showing an activity from YouTube']")
    var liked_videos = collector(all_cards)
    // download json
    download("liked_videos.json", JSON.stringify(liked_videos))

}

main()



基本上,它会收集所有喜欢的视频的详细信息,并为每个喜欢的视频创建一个

key: video_ID - Value: [title,video_length, date, time]
对象。

然后它会自动将 json 下载为文件。


0
投票

能够获取喜欢、不喜欢以及次要标题(或副标题或副标题)的版本,后者有时很有用,因为对于音乐来说,如果艺术家姓名不在标题本身中而是在标题中,则可以帮助识别艺术家而是副标题或频道名称。当遇到无效的视频 ID(使用 URL 而不是视频 ID 标题)“www...”时,下面的材料会被破坏,但我可以使用帮助来解决这个问题...也许是受到开头的修复的启发这个线程。

function collector(all_cards) { 
    var videos = {};
    all_cards.forEach(card => {
        let action = card.innerText.split("\n")[1].split(" ")[0];
        if (action === "Liked" || action === "Disliked") {
            let a_links = card.querySelectorAll("a");
            let details = a_links[0];
            let url = details.href.split("?v=")[1];
            let video_length = a_links[3].innerText;
            let time = a_links[2].parentElement.innerText.split(" • ")[0];
            let title = details.innerText;
            let date = card.closest("[data-date]").getAttribute("data-date");
            let secondary_headline = card.innerText.split("\n")[2].replace(/"/g, "");
            videos[url] = [title, video_length, date, time, action, secondary_headline];
        }
    });

    return videos;
}


// https://stackoverflow.com/questions/57709550/how-to-download-text-from-javascript-variable-on-all-browsers
function download(filename, text, type = "text/plain") {
    // Create an invisible A element
    const a = document.createElement("a");
    a.style.display = "none";
    document.body.appendChild(a);

    // Set the HREF to a Blob representation of the data to be downloaded
    a.href = window.URL.createObjectURL(
        new Blob([text], { type })
    );
    
    // Use download attribute to set set desired file name
    a.setAttribute("download", filename);

    // Trigger the download by simulating click
    a.click();

    // Cleanup
    window.URL.revokeObjectURL(a.href);
    document.body.removeChild(a);
}

function main() {
    // gather relevant elements
    var all_cards = document.querySelectorAll("div[aria-label='Card showing an activity from YouTube']")
    var liked_videos = collector(all_cards)
    // download json
    download("liked_videos.json", JSON.stringify(liked_videos))

}

main()
© www.soinside.com 2019 - 2024. All rights reserved.