JS не может получить доступ к глобальной переменной внутри функции

Я пытаюсь создать простой веб-скрейпер, используя Node и Puppeteer, чтобы получить заголовки постов на Reddit, но у меня проблемы с доступом к глобальной переменной SUBREDDIT_NAME только из одной функции, extractItems(). Он отлично работает с любой другой функцией, но для этой мне нужно создать локальную переменную с тем же значением, чтобы она работала.

Я совершенно неправильно понимаю переменную в Javascript?

Я пробовал все, что мог придумать, и единственное, что работает, - это создать локальную переменную внутри ExtractedItems() со значением «новости», иначе я ничего не получаю.

const fs = require('fs');
const puppeteer = require('puppeteer');
const SUBREDDIT = (subreddit_name) => `https://reddit.com/r/${subreddit_name}/`;
const SUBREDDIT_NAME= "news";


function extractItems() {
  const extractedElements = document.querySelectorAll(`a[href*='r/${SUBREDDIT_NAME}/comments/'] h3`);
  const items = [];
  for (let element of extractedElements) {
    items.push(element.innerText);
  }
  return items;
}

async function scrapeInfiniteScrollItems(
  page,
  extractItems,
  itemTargetCount,
  scrollDelay = 1000,
) {
  let items = [];
  try {
    let previousHeight;5
    while (items.length < itemTargetCount) {
      items = await page.evaluate(extractItems);
      previousHeight = await page.evaluate('document.body.scrollHeight');
      await page.evaluate('window.scrollTo(0, document.body.scrollHeight)');
      await page.waitForFunction(`document.body.scrollHeight > ${previousHeight}`);
      await page.waitFor(scrollDelay);
    }
  } catch(e) { }
  return items;
}

(async () => {
  // Set up browser and page.
  const browser = await puppeteer.launch({
    headless: false,
    args: ['--no-sandbox', '--disable-setuid-sandbox'],
  });
  const page = await browser.newPage();
  page.setViewport({ width: 1280, height: 926 });

  // Navigate to the demo page.
  await page.goto(SUBREDDIT(SUBREDDIT_NAME));

  // Scroll and extract items from the page.
  const items = await scrapeInfiniteScrollItems(page, extractItems, 100);

  // Save extracted items to a file.
  fs.writeFileSync('./items.txt', items.join('\n') + '\n');

  // Close the browser.
  await browser.close();
})();

Я ожидаю текстовый файл со 100 первыми найденными заголовками, но он работает только тогда, когда я жестко запрограммирую сабреддит в функцию extractItems().

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
204
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что функция extractItems преобразуется в строку (без обработки литерала шаблона) и выполняется в контексте страницы, где нет переменной SUBREDDIT_NAME.

Вы можете исправить это, сделав что-то вроде этого:

function extractItems(name) {
  const extractedElements = document.querySelectorAll(`a[href*='r/${name}/comments/'] h3`);
  const items = [];
  for (let element of extractedElements) {
    items.push(element.innerText);
  }
  return items;
}

page.evaluate(`(${extractItems})(${SUBREDDIT_NAME})`)

Разве это не должно быть (${extractItems})(${SUBREDDIT_NAME}) или ((${extractItems})(${SUBREDDIT_NAME}))?

Md. Abu Taher 24.06.2019 10:35

@Md.AbuTaher Да, это правильно, я внес правку.

Titus 24.06.2019 11:40

Почему вы используете конкатенацию строк? Вы можете назвать это так: page.evaluate(extractItems, SUBREDDIT_NAME)

Thomas Dondorf 24.06.2019 19:41

Другие вопросы по теме