You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Puppeteer表格分页问题:Next按钮仅触发一次点击操作

Puppeteer分页点击仅触发一次的问题解决

问题描述

使用Puppeteer实现表格多页导航时,循环点击「Next」按钮切换分页,count变量显示循环迭代次数正确,但点击事件仅触发一次,后续点击无效。

原代码

import puppeteer from "puppeteer";

export const getNigeriaPortsLineups = async () => {
  let browser;
  try {
    browser = await puppeteer.launch({
      ignoreHTTPSErrors: true,
      headless: false,
      timeout: 60000,
    });
    const width = 1920,
      height = 1080;

    const page = await browser.newPage();
    await page.setViewport({ width, height });
    await page.setUserAgent(
      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
    );
    await page.goto("https://shippos.nigerianports.gov.ng/", {
      timeout: 60000,
    });

    await page.evaluate(async () => {
      let nextButton = document.querySelector("#Apapa2_next") as HTMLElement;
      const tableRows = document.querySelectorAll("#Apapa2 tbody tr");
      const sugarRows = Array.from(tableRows).map((row) => {
        return Array.from(row.querySelectorAll("td")).map((cell) =>
          cell.textContent.trim()
        );
      });

      let count = 0;
      while (count <= 4) {
        console.log(count);
        await new Promise((resolve) => setTimeout(resolve, 2000));
        nextButton.click()
        
        count++;
      }

      // while (nextButton && !nextButton.classList.contains("disabled")) {
      //   nextButton.click();
      //   await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait for a second before clicking again
      // }
    });
  } catch (error) {
    console.error(error);
  } finally {
    // if (browser) await browser.close();
  }
};

问题原因

  1. DOM元素引用失效:一开始获取的nextButton是第一页的元素,分页切换后页面会重新渲染分页控件,原按钮元素已被移除,后续点击的是失效的DOM引用,自然无反应。
  2. 未确保页面更新完成:单纯用setTimeout等待,无法保证新分页元素加载完成,即使重新获取按钮也可能拿到未更新的元素。

修复后的代码

import puppeteer from "puppeteer";

export const getNigeriaPortsLineups = async () => {
  let browser;
  try {
    browser = await puppeteer.launch({
      ignoreHTTPSErrors: true,
      headless: false,
      timeout: 60000,
    });
    const width = 1920,
      height = 1080;

    const page = await browser.newPage();
    await page.setViewport({ width, height });
    await page.setUserAgent(
      "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
    );
    await page.goto("https://shippos.nigerianports.gov.ng/", {
      timeout: 60000,
      waitUntil: "networkidle2" // 确保页面初始加载完成
    });

    // 收集所有页面的数据
    const allRows = [];
    let count = 0;
    const maxPages = 4; // 最多翻4页

    while (count <= maxPages) {
      // 获取当前页表格数据
      const currentRows = await page.evaluate(() => {
        const tableRows = document.querySelectorAll("#Apapa2 tbody tr");
        return Array.from(tableRows).map(row => 
          Array.from(row.querySelectorAll("td")).map(cell => cell.textContent.trim())
        );
      });
      allRows.push(...currentRows);

      try {
        // 等待下一页按钮存在且未禁用
        await page.waitForSelector("#Apapa2_next:not(.disabled)", { timeout: 5000 });
        // 点击按钮(Puppeteer会自动等待元素可交互)
        await page.click("#Apapa2_next");
        // 等待表格内容更新,确保分页切换完成
        await page.waitForFunction(
          (prevRowCount) => document.querySelectorAll("#Apapa2 tbody tr").length !== prevRowCount,
          {},
          currentRows.length
        );
      } catch (err) {
        // 无下一页时退出循环
        break;
      }

      count++;
    }

    console.log("所有页面数据:", allRows);
  } catch (error) {
    console.error(error);
  } finally {
    if (browser) await browser.close();
  }
};

关键修复点

  • 放弃缓存按钮引用:使用page.waitForSelector和page.click,每次操作都重新查找按钮,自动适配DOM更新后的元素。
  • 等待元素可交互:page.click会自动等待元素处于可点击状态,比直接调用DOM的click方法更可靠。
  • 监听页面内容变化:用page.waitForFunction监听表格行数变化,确保分页切换完成后再进行下一次操作,替代固定时长的setTimeout。
  • 完整收集数据:修复原代码仅获取第一页数据的问题,循环中收集每一页的表格内容。

内容的提问来源于stack exchange,提问作者user12504353

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:16:28