我刚刚开始学习语法分析,遇到了一个问题.我可能误解了什么或写了什么,但我不明白是什么

const puppeteer = require(`puppeteer`);

(async () => {
    const browser = await puppeteer.launch({headless:false})
    const page = await browser.newPage()
    await page.goto('https://www.agsvyazi.ru/beeline/numbers/index.page.0.htm',{waitUntil: 'load'})

    let pages = 131;

    let idx = 0;

    const allPhns = [];

    while(pages > idx){

        await new Promise(resolve => setTimeout(resolve, 3000));
        
        let arr = await page.evaluate(() => {

            let elem = Array.from(document.querySelectorAll("div.fl.number-table"), el => el.innerText)
            return elem
        })
        
        allPhns.push(...arr)

        // hrefPer = document.querySelector('div.listing a:last-child').href

        //await page.goto(document.querySelector('div.listing a:last-child').href)

        await page.goto(document.querySelector('div.listing a:last-child').href, {waitUntil: 'load'})

        idx +=1 
    }


    console.log(allPhns)

})()

我同时try 了Page.goto和Page.Click.我在元素的代码中搜索了很多,try 了querySelector()和querySelectorAll()不同的"路径".我不明白问题出在哪里

推荐答案

我收到的错误与您运行代码时的错误不同:

script.js:30
        await page.goto(document.querySelector('div.listing a:last-child').href, {waitUntil: 'load'})
                        ^

ReferenceError: document is not defined

node 中不存在document.它只在浏览器中,这意味着你只能在evaluate回调中访问它:

const puppeteer = require("puppeteer"); // ^21.6.0

const base = "https://www.agsvyazi.ru/beeline/numbers/index.page.";

let browser;
(async () => {
  browser = await puppeteer.launch({headless: false});
  const [page] = await browser.pages();
  await page.setJavaScriptEnabled(false);
  await page.setRequestInterception(true);
  page.on("request", req =>
    req.url().startsWith(base) ? req.continue() : req.abort()
  );
  const data = [];

  for (let i = 1; i < 10 /* remove this to scrape everything */; i++) {
    try {
      const url = base + i * 100 + ".htm";
      console.log(url);
      await page.goto(url, {waitUntil: "domcontentloaded"});
      const chunk = await page.$$eval(
        ".fl.number-table",
        els => els.map(e => e.textContent.trim())
      );
      data.push(chunk);
    }
    catch (err) {
      console.error(err);
      break;
    }
  }

  console.log(data);
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());

除非你想限制你的请求,否则await new Promise(resolve => setTimeout(resolve, 3000));就是not necessary.如果你确实需要睡觉,一个更清晰的方法是使用import {setTimeout} from "node:timers/promises";.


更进一步,如果我理解正确的话,我认为你不需要Puppeteer,因为数据已经在静态HTML中了.我建议使用内置的fetch和轻量级的HTML解析器Cheerio:

const cheerio = require("cheerio"); // ^1.0.0-rc.12

const base = "https://www.agsvyazi.ru/beeline/numbers/";

(async () => {
  let url = "index.page.100.htm";
  const data = [];

  for (let i = 0; i < 10 /* remove this to scrape everything */; i++) {
    try {
      console.log(base + url);
      const res = await fetch(base + url);

      if (!res.ok) {
        break;
      }

      const $ = cheerio.load(await res.text());
      const chunk = [...$(".fl.number-table")].map(e =>
        $(e).text().trim()
      );
      data.push(chunk);
      url = $("div.listing a:last-child").attr("href");
    }
    catch (err) {
      console.error(err);
      break;
    }
  }

  console.log(JSON.stringify(data, null, 2));
})();

Javascript相关问答推荐

React:未调用useState变量在调试器的事件处理程序中不可用

如何用显示网格平滑地将元素从一个地方移动到另一个地方?

无法在nextjs应用程序中通过id从mongoDB删除'

如何从一个列表中创建一个2列的表?

单击ImageListItemBar的IconButton后,在Material—UI对话框中显示图像

在服务器上放置了Create Reaction App Build之后的空白页面

分层树视图

setcallback是什么时候放到macrotask队列上的?

无法读取未定义错误的属性路径名''

并不是所有的iframe都被更换

更新动态数据中对象或数组中的所有值字符串

WP Bootstrap NavWaker:下拉菜单一次打开所有下拉菜单

第三方包不需要NODE_MODULES文件夹就可以工作吗?

使用带有HostBinding的Angular 信号来更新样式?

不同表的条件API端点Reaction-redux

通过跳过某些元素的对象进行映射

使用Reaction窗体挂钩注册日历组件

为什么当雪碧的S在另一个函数中时,Phaser不能加载它?

如何将对象推送到firestore数组?

在执行console.log(new X())时记录一个字符串