Есть NodeJS код, но почему-то при формировании списка ITOG этот код пишет в каждый элемент списка ITOG, а конкретно в часть элемента где указана "DATA_PUBLISHED" всегда значение "1 month ago" , хотя там должны быть разные значения, например:
"4 days ago" или например "7 weeks ago"
А устанавливает он в DATA_PUBLISHED первое найденное значение из текста в переменой SAVED_CONTENT и далее почему-то для других элементов списка ITOG он ставит это первое найденное значение "1 month ago"
Вот структура каждого элемента:
return `${id_of_video}@@@${views}^^^${views_per_hour}~~~${it_is_short_or_not}↜↜↜${name_of_video}&&&seconds${seconds}***DATA_PUBLISHED${DATA_PUBLISHED}`;
Код:
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
var SAVED_CONTENT = [[SAVED_CONTENT]];
function convertViews(savedContent) {
savedContent = savedContent.replace(/"accessibilityData":\{"label":"([\d.]+)\s*([KkMm]|million)?\s*views"\}\},"simpleText":"([\d.]+)\s*([KkMm]|million)?\s*views"/g, function (match, num1, unit1, num2, unit2) {
var multiplier1 = unit1 === 'M' || unit1 === 'm' || unit1 === 'million' ? 1000000 : unit1 === 'K' || unit1 === 'k' ? 1000 : 1;
var multiplier2 = unit2 === 'M' || unit2 === 'm' || unit2 === 'million' ? 1000000 : unit2 === 'K' || unit2 === 'k' ? 1000 : 1;
var views1 = Math.round(parseFloat(num1) * multiplier1);
var views2 = Math.round(parseFloat(num2) * multiplier2);
return '"accessibilityData":{"label":"' + views1 + ' views"}},"simpleText":"' + views2 + ' views"';
});
savedContent = savedContent.replace(/"viewCountText":\{"simpleText":"([\d,]+)\s*views"\}/g, function (match, num) {
var views = parseInt(num.replace(/,/g, ''), 10);
return '"viewCountText":{"simpleText":"' + views + ' views"}';
});
return savedContent;
}
SAVED_CONTENT = convertViews(SAVED_CONTENT);
[[SAVED_CONTENT]] = SAVED_CONTENT;
const dom = new JSDOM(SAVED_CONTENT);
const document = dom.window.document;
const videoElements = Array.from(document.querySelectorAll("#contents ytd-video-renderer"));
function timeTextToHours(timeText) {
const regex = /(\d+)\s*(\D+)/g;
let hours = 0;
let match;
while ((match = regex.exec(timeText)) !== null) {
const value = parseInt(match[1], 10);
const unit = match[2].toLowerCase();
if (unit.includes("minutes") || unit.includes("minute")) {
hours += value / 60;
} else if (unit.includes("hours") || unit.includes("hour")) {
hours += value;
} else if (unit.includes("days") || unit.includes("day")) {
hours += value * 24;
} else if (unit.includes("weeks") || unit.includes("week")) {
hours += value * 24 * 7;
} else if (unit.includes("months") || unit.includes("month")) {
hours += value * 24 * 30;
} else if (unit.includes("years") || unit.includes("year")) {
hours += value * 24 * 365;
}
}
return hours;
}
const ITOG = videoElements.map((videoElement) => {
let id_of_video = videoElement.querySelector("a#thumbnail") && videoElement.querySelector("a#thumbnail").href.split("?v=")[1] || "";
if (!id_of_video) {
id_of_video = videoElement.querySelector("a.yt-simple-endpoint") && videoElement.querySelector("a.yt-simple-endpoint").href.split("?v=")[1] || "";
}
// Remove everything after "&pp=" till "@@@"
id_of_video = id_of_video.split("&pp=")[0];
const videoTitleElement = videoElement.querySelector("#video-title");
const ariaLabel = videoTitleElement ? videoTitleElement.getAttribute("aria-label") : "";
const viewsMatch = ariaLabel.match(/([\d,]+)\sviews?/);
const views = viewsMatch ? parseInt(viewsMatch[1].replace(/,/g, ''), 10) : 0;
function extractTimeText(videoElementText) {
const publishedTimeTextRegex = /"publishedTimeText":\{"simpleText":"([^"]+)"\}/;
const publishedTimeTextMatch = videoElementText.match(publishedTimeTextRegex);
return publishedTimeTextMatch ? publishedTimeTextMatch[1] : "";
}
function textToSeconds(dataPublished) {
var timeValueMatch = dataPublished.match(/\d+/);
var timeUnitMatch = dataPublished.match(/[a-zA-Z]+/);
if (!timeValueMatch || !timeUnitMatch) {
return -1;
}
var timeValue = parseInt(timeValueMatch[0]);
var timeUnit = timeUnitMatch[0].toLowerCase();
var seconds;
switch (timeUnit) {
case 'years':
case 'year':
seconds = timeValue * 365 * 24 * 60 * 60;
break;
case 'months':
case 'month':
seconds = timeValue * 30 * 24 * 60 * 60;
break;
case 'weeks':
case 'week':
seconds = timeValue * 7 * 24 * 60 * 60;
break;
case 'days':
case 'day':
seconds = timeValue * 24 * 60 * 60;
break;
case 'hours':
case 'hour':
seconds = timeValue * 60 * 60;
break;
default:
// console.error("Invalid time unit:", timeUnit);
return -1;
}
return seconds;
}
const DATA_PUBLISHED = extractTimeText(SAVED_CONTENT);
const seconds = textToSeconds(DATA_PUBLISHED);
var VPH = views / (seconds / 3600);
var views_per_hour = Math.round(VPH * 100) / 100; // Round to 2 decimal places
const shortsURL = `/shorts/${id_of_video}`;
const it_is_short_or_not = SAVED_CONTENT.includes(shortsURL) ? "YES_SHORT" : "NO_SHORT";
if (it_is_short_or_not === "YES_SHORT" && !id_of_video) {
id_of_video = videoElement.querySelector("a.yt-simple-endpoint") && videoElement.querySelector("a.yt-simple-endpoint").href.split("/shorts/")[1] || "";
}
const name_of_video = videoTitleElement ? videoTitleElement.textContent.trim() : "";
return `${id_of_video}@@@${views}^^^${views_per_hour}~~~${it_is_short_or_not}↜↜↜${name_of_video}&&&seconds${seconds}***DATA_PUBLISHED${DATA_PUBLISHED}`;
});
// console.log(ITOG);
[[ITOG]] = ITOG;