🎯 一款可定制、具备反检测功能的云浏览器,由自主研发的 Chromium驱动,专为网页爬虫AI 代理设计。👉立即试用
返回博客

如何处理网页抓取中的分页:每种类型解释

Ava Wilson
Ava Wilson

Expert in Web Scraping Technologies

30-Jun-2026

TL;DR:

  • 有四种分页类型,每种都有其自己的停止条件。 下一页按钮、编号页面、加载更多和无限滚动 — 如果停止条件错误,你要么错过页面,要么永远循环。
  • 遵循网站自己的“下一步”链接;不要猜测 URL。 读取 li.next a 并逐页跟随,可以避免跳过间隙和不规则编号,而 ?page=N 循环则会默默跳过这些页面。
  • 无限滚动在页面停止增长时结束。 滚动、等待,并比较 scrollHeight — 当它停止增加时,你已到达结束;这是唯一可靠的信号。
  • 分页是你被速率限制的地方。 从一个 IP 上走过几十个页面正是反机器人系统监视的模式;使用住宅代理和真实浏览器可以保持运行的干净。
  • 一切都在 Scrapeless Scraping Browser 上运行,使用简单的 Puppeteer。 创建会话,导航,提取,推进 — 云浏览器处理渲染和反检测,因此页面持续加载。
  • 免费开始。 新的 Scrapeless 账户包括免费的 Scraping Browser 运行时 — 在 app.scrapeless.com 注册。

介绍:分页是破坏抓取器的部分

抓取一页是简单的。抓取所有页面是大多数抓取器安静失败的地方 — 它们抓取第一页后停止,或循环到结束获取空页面,或者在过程中被反机器人防护 速率限制。原因在于“分页”并不是一件事。一个网站使用四种机制中的一种,每种需要不同的推进方式和不同的完成检测方式。

正确识别类型后,其他的就是机械的:提取当前页面,找到前进的方式,重复直到停止条件。错误则可能导致 — 假设 ?page=N 而网站使用“加载更多”按钮,或固定等待时间而不是等待新内容 — 这样你会丢失数据而没有错误来提示你。

本指南涵盖所有四种类型,并在 Scrapeless Scraping Browser 上运行,它是一个与 Puppeteer 连接的抗检测云浏览器。下面的下一按钮示例是针对一个实时分页网站运行的;其他模式共享同样的循环形状。


四种分页类型

类型 如何推进 停止条件
下一按钮 跟随 next 链接的 href 下一链接消失
编号页面 构建 ?page=N 或读取最高数字 N 超过最后一页
加载更多 点击“加载更多”按钮 按钮消失
无限滚动 滚动到底部 scrollHeight 停止增长

最常见的错误是把下一按钮或加载更多的网站当作有干净编号 URL 的网站来处理。遵循网站自己的控件,而不是构造 URL,即使编号存在间隙也能保持正确。


为什么选择 Scrapeless Scraping Browser

Scrapeless Scraping Browser 是一个可定制、抗检测的云浏览器,专为网络爬虫和 AI 代理设计。特别是针对多页抓取,它提供:

  • 标准 Puppeteer 连接Puppeteer.connect() 返回一个正常的 Browser,因此你的导航和提取代码保持不变。
  • 在 195 个以上国家的住宅代理 — 在不触发速率限制的情况下浏览多个页面。
  • 抗检测指纹识别 — 长时间抓取表现为真实浏览器,因此后续页面不断渲染。
  • 云端 JS 渲染 — 加载更多和无限滚动内容(由 JavaScript 构建)实际显示。
  • 会话持久性 — 在整个抓取过程中保持 Cookie 活跃。

在免费计划上获取你的 API 密钥,访问 app.scrapeless.com


先决条件


安装

bash Copy
npm install @scrapeless-ai/sdk puppeteer-core
bash Copy
export SCRAPELESS_API_KEY="your_api_token_here"

连接

javascript Copy
import { Puppeteer } from '@scrapeless-ai/sdk';

const browser = await Puppeteer.connect({
  apiKey: process.env.SCRAPELESS_API_KEY,
  sessionName: 'pagination',
  proxyCountry: 'US',
  sessionTTL: 300,
});

const page = await browser.newPage();

类型 1 — 下一按钮(最稳健)

跟随网站自己的“下一步”链接直到它消失。这存活于编号间隙,因为你从未构造 URL — 你读取网站提供的那个:

javascript Copy
const BASE = 'https://quotes.toscrape.com';
let url = `${BASE}/page/1/`;
const items = [];
let pages = 0;

while (url) {
  await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
  pages++;

  const pageItems = await page.evaluate(() =>
[...document.querySelectorAll('.quote .text')].map((q) => q.textContent),
  );
  items.push(...pageItems);

  // 读取下一个链接;在最后一页时为null
  const next = await page.evaluate(() => {
    const a = document.querySelector('li.next a');
    return a ? a.getAttribute('href') : null;
  });
  url = next ? new URL(next, BASE).href : null;
}

console.log(pages, '页,', items.length, '项目');
// 10页,100个项目

li.next a 不再存在时,循环自然结束——无需猜测页面数量,也没有越界。

在免费计划上获取您的API密钥:app.scrapeless.com


类型 2 — 编号页面

当网站展示清晰的编号URL和可见的最后一页时,先读取最高页码,然后进行迭代。仍然更喜欢读取最后一页链接而不是假设它:

javascript Copy
await page.goto(`${BASE}/page/1/`, { waitUntil: 'domcontentloaded' });
// 例如,如果存在,则读取最后一个分页器链接,否则继续前进,直到页面没有内容
for (let n = 1; ; n++) {
  await page.goto(`${BASE}/page/${n}/`, { waitUntil: 'domcontentloaded' });
  const count = await page.evaluate(() => document.querySelectorAll('.quote').length);
  if (count === 0) break;   // 空页面 = 超过末尾
  // ...提取
}

空页面检查是安全网:即使您误判了最后一页的页码,一旦页面返回没有项目,您就会停止。


类型 3 — 加载更多按钮

内容是一页;一个按钮可以添加更多。单击它直到它消失,在单击之间等待新项目:

javascript Copy
await page.goto(TARGET, { waitUntil: 'domcontentloaded' });
while (true) {
  const before = await page.evaluate(() => document.querySelectorAll('.item').length);
  const btn = await page.$('button.load-more');
  if (!btn) break;                       // 没有更多按钮 = 完成
  await btn.click();
  await page.waitForFunction(
    (n) => document.querySelectorAll('.item').length > n,
    {},
    before,
  );                                      // 等待新项目,而不是固定的延迟
}

等待项目数量增长——而不是固定延迟——使得在响应较慢情况下更可靠。


类型 4 — 无限滚动

新项目在滚动时加载。滚动,等待,当页面高度停止增加时停止:

javascript Copy
await page.goto(TARGET, { waitUntil: 'domcontentloaded' });
let prevHeight = 0;
while (true) {
  const height = await page.evaluate(() => document.body.scrollHeight);
  if (height === prevHeight) break;       // 高度停止增长 = 结束
  prevHeight = height;
  await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
  await new Promise((r) => setTimeout(r, 1500)); // 让下一批加载
}
const items = await page.evaluate(() =>
  [...document.querySelectorAll('.item')].map((el) => el.textContent),
);

您得到的返回值

无论类型如何,您都会得到一个通过页面组装的平面列表——对于验证下一个按钮的运行,跨10页有100个项目。一些诚实的观察:

  • 防止重复。 加载更多和无限滚动可能会重新发出项目;以稳定的id为关键。
  • 限制循环。 添加最大页面保护,以免不合规的网站无限循环。
  • 注意稳定选择器。 如果 li.next 或加载更多按钮的类发生变化,循环将提前结束——当计数看起来较低时重新检查选择器。
  • 控制爬行速度。 在页面之间的短暂延迟和适度的并发可以保持IP声誉信号的清洁。

结论:选择类型,然后循环是机械的

每个分页爬虫都具有相同的结构——提取、前进、检查停止条件——一旦您确定了该网站使用的四种类型中的哪一种。遵循网站自身的下一个/加载更多控制,而不是猜测URL,并在真实信号上停止(没有下一个链接、空页面、缺失按钮、稳定高度)。在Scrapeless Scraping Browser上运行可以保持长时间爬取渲染且不被阻塞,通过 住宅代理出口。要收集页面URL以进行爬取,请参阅 Etsy抓取工具指南抓取浏览器产品页面文档 涵盖了完整的SDK范围。阅读网站的控件,等待内容而不是时钟,并保护循环。


准备构建您的 AI 驱动的数据管道吗?

加入我们的社区,以领取免费计划并与构建多页面爬虫的开发人员联系:Discord · Telegram
app.scrapeless.com 注册以获得免费的 Scraping Browser 运行时,并将上述模式调整为您的工作流所需的分页网站。有关规模的详细信息,请参见 定价


常见问题解答

问:我怎么知道一个网站使用哪种分页类型?
查看页面:“下一页”链接是下一按钮;数字链接是编号页面;“加载更多”按钮是加载更多;无控制的滚动新内容是无限滚动。许多网站混合使用两种——处理加载数据的那种。

问:为什么我的 ?page=N 循环会错过数据?
因为该网站没有使用干净的编号 URL,或者编号存在间隔。请遵循网站自己的下一链接,而不是构建 URL。

问:我如何停止无限滚动循环?
在每次滚动之前和之后比较 document.body.scrollHeight。当它停止增加时,就没有更多内容可加载。

问:我需要代理来进行多页抓取吗?
通常需要——从一个 IP 地址访问许多页面通常会触发速率限制。通过 proxyCountry 固定住宅出口并调整抓取速度。

问:我如何避免在抓取过程中被封锁?
在页面之间增加短暂延迟,保持适度的并发性,并使用真实的反检测浏览器进行抓取,以便后续页面继续渲染。

问:我可以在没有 AI 代理的情况下运行这个吗?
可以。它是通过 Scrapeless 会话的普通 Puppeteer——不需要代理。

在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。

最受欢迎的文章

目录