Skip to content

Instantly share code, notes, and snippets.

@ItsJonQ
Created February 13, 2023 21:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ItsJonQ/d89fdc0ce5c732c9442cee34021f056b to your computer and use it in GitHub Desktop.
Save ItsJonQ/d89fdc0ce5c732c9442cee34021f056b to your computer and use it in GitHub Desktop.
Get YouTube history in the browser
var getViewCount = (views = '') => {
if (!views) return null;
const viewBase = views.split(" ")[0];
if (viewBase.includes("M")) {
return parseInt(views.replace("M", "")) * 1000000;
}
if (viewBase.includes("K")) {
return parseInt(views.replace("K", "")) * 1000;
}
return Number(viewBase);
};
var isShort = (videoLength = '') => {
if (!videoLength) return false;
return videoLength.toLowerCase().includes("short");
}
var getDurationSeconds = (duration) => {
if (isShort(duration)) {
return 60;
}
const [m, s] = duration.split(":");
return parseInt(m) * 60 + parseInt(s);
};
var getDate = (date) => {
const [day, month, year] = date.split(" ");
let finalDate = date;
if (!year && !month) {
return date
}
if (!year) {
finalDate = `${day} ${month} ${new Date().getFullYear()}`;
}
return finalDate.replace(/,/g, "");
};
var sanitize = (str) =>
str ? `${str.replace(/"/g, "").replace(/,/g, " ").trim()}` : null;
var getVideos = () => {
const videos = document.querySelectorAll("ytd-video-renderer");
const data = Array.from(videos).map((video) => {
const titleNode = video.querySelector(".title-and-badge a");
const url = titleNode.getAttribute("href");
const titleTextNode = titleNode.querySelector("yt-formatted-string");
const title = titleTextNode ? titleTextNode.innerText : null;
const channelNameNode = video.querySelector(".ytd-channel-name a");
const channelUrl = channelNameNode.getAttribute("href");
const channelName = channelNameNode ? channelNameNode.innerText : null;
const metaItemNode = video.querySelector(
"#metadata-line .inline-metadata-item"
);
const views = metaItemNode ? metaItemNode.innerText : null;
const descriptionNode = video.querySelector("#description-text");
const description = descriptionNode ? descriptionNode.innerText : null;
const videoLengthNode = video.querySelector(
"ytd-thumbnail-overlay-time-status-renderer"
);
const videoLength = videoLengthNode ? videoLengthNode.innerText : null;
const length = sanitize(videoLength);
const duration = length ? getDurationSeconds(length) : null;
const videoType = isShort(videoLength) ? "short" : "video";
const containerNode = video.closest("ytd-item-section-renderer");
const dateNode = containerNode.querySelector(
"#title.ytd-item-section-header-renderer"
);
const date = dateNode ? dateNode.innerText : null;
return {
title: sanitize(title),
url: `https://www.youtube.com${url}`,
channelUrl: `https://www.youtube.com${channelUrl}`,
channelName: sanitize(channelName),
views: getViewCount(views),
description: sanitize(description),
duration,
videoType,
date: getDate(date),
};
});
return data;
};
var getVideoCSV = () => {
const csv = [
[
"title",
"description",
"url",
"channelName",
"channelUrl",
"views",
"duration",
"videoType",
"date",
].join(","),
];
const data = getVideos().forEach((video) => {
const {
title,
description,
url,
channelName,
channelUrl,
views,
duration,
videoType,
date,
} = video;
csv.push(
[
title,
description,
url,
channelName,
channelUrl,
views,
duration,
videoType,
date,
].join(",")
);
});
return csv.join("\n");
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment