Javascript JS无法访问函数内部的全局变量

Javascript JS无法访问函数内部的全局变量,javascript,node.js,puppeteer,Javascript,Node.js,Puppeteer,我正在尝试使用Node和Puppeter制作一个简单的webscraper,以获取reddit上帖子的标题,但在仅从一个函数extractItems()中访问全局变量SUBREDDIT_NAME时遇到问题。它适用于所有其他函数,但对于这个函数,我必须使一个局部变量具有相同的值,它才能工作 我是否完全误解了Javascript中的变量范围 我已经尝试了我能想到的一切,唯一有效的方法是在extractedEditEMS()中创建一个局部变量,值为“news”,否则我什么也得不到 const fs =

我正在尝试使用Node和Puppeter制作一个简单的webscraper,以获取reddit上帖子的标题,但在仅从一个函数extractItems()中访问全局变量SUBREDDIT_NAME时遇到问题。它适用于所有其他函数,但对于这个函数,我必须使一个局部变量具有相同的值,它才能工作

我是否完全误解了Javascript中的变量范围

我已经尝试了我能想到的一切,唯一有效的方法是在extractedEditEMS()中创建一个局部变量,值为“news”,否则我什么也得不到

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();
})();
const fs=require('fs');
const puppeter=require('puppeter');
const SUBREDDIT=(SUBREDDIT_name)=>`https://reddit.com/r/${subreddit_name}/`;
const SUBREDDIT_NAME=“news”;
函数提取项(){
const extractedElements=document.querySelectorAll(`a[href*='r/${SUBREDDIT\u NAME}/comments/']h3`);
常量项=[];
for(提取元素的let元素){
items.push(element.innerText);
}
退货项目;
}
async函数用于查询滚动项(
页
提取项目,
itemTargetCount,
滚动延迟=1000,
) {
设项目=[];
试一试{
让我们来看看你的身高
while(items.length${previousHeight}`);
等待页面。等待(滚动延迟);
}
}捕获(e){}
退货项目;
}
(异步()=>{
//设置浏览器和页面。
const browser=wait puppeter.launch({
无头:错,
参数:['--no sandbox','--disable setuid sandbox'],
});
const page=wait browser.newPage();
setViewport({宽度:1280,高度:926});
//导航到演示页面。
等待page.goto(SUBREDDIT(SUBREDDIT_NAME));
//滚动并从页面中提取项目。
const items=wait scrapeScrollItems(第页,extractItems,100);
//将提取的项目保存到文件中。
fs.writeFileSync('./items.txt',items.join('\n')+'\n');
//关闭浏览器。
等待浏览器关闭();
})();

我希望文本文件具有100个首次找到的标题,但它只有在我将子Reddit硬编码到extractItems()函数中时才起作用。

问题是
extractItems
函数被转换为字符串(不处理模板文本)并在没有
SUBREDDIT\u 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\u 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.AbuTaher是的,这是正确的,我进行了编辑。为什么使用字符串连接?你可以这样称呼它:
page.evaluate(extractItems,SUBREDDIT\u NAME)
应该是
(${extractItems})(${SUBREDDIT\u NAME})
还是(
(${extractItems})(${SUBREDDIT\u NAME})
)@Md AbuTaher是的,这是正确的,我做了编辑。为什么要使用字符串连接?您可以这样称呼它:
page.evaluate(extractItems,SUBREDDIT\u NAME)