Задать вопрос

Почему в всех элементах списка одно и тоже значение?

Есть 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;
  • Вопрос задан
  • 55 просмотров
Подписаться 1 Средний 5 комментариев
Решения вопроса 1
Starina_js
@Starina_js
full-stack web dev
Кажется проблема связана с использованием одной и той же переменной DATA_PUBLISHED внутри цикла map(). Каждая итерация цикла должна иметь свою собственную переменную DATA_PUBLISHED, чтобы сохранить соответствующие значения для каждого элемента списка ITOG.

Вообще этот код хотя бы выровнять, визуально поправить)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы