新手求助:如何用Puppeteer抓取15000个动态加载的href链接?
解决Puppeteer抓取动态分页加载的所有Href链接问题
你的问题出在只抓取了初始加载的第一页内容,没有处理分页点击逻辑。因为网站是通过点击下一页按钮将新内容追加到当前页面,所以需要循环执行「抓取当前页链接 → 点击下一页 → 等待内容加载」的流程,直到所有页面加载完成。
以下是改进后的代码:
const puppeteer = require('puppeteer'); async function scrapeAllHrefs(URL) { const browser = await puppeteer.launch({ headless: false }); // 调试时设为false可直观观察页面变化 const page = await browser.newPage(); await page.goto(URL, { timeout: 0, waitUntil: 'networkidle0' }); const allHrefs = new Set(); // 用Set自动去重,避免重复抓取导航栏等固定链接 while (true) { // 抓取当前页面的目标链接,建议替换为更精确的选择器(比如条目容器内的a标签) const currentHrefs = await page.evaluate(() => { // 示例:仅抓取类名为item-container下的a标签,替换成你目标元素的选择器 return Array.from(document.querySelectorAll('.item-container a'), el => el.href); }); // 将当前页链接存入Set currentHrefs.forEach(href => allHrefs.add(href)); // 查找下一页按钮,替换为网站实际的下一页选择器(比如.next-btn、#next-page) const nextButton = await page.$('.next-page'); if (!nextButton) break; // 无下一页按钮时退出循环 // 检查按钮是否处于禁用状态(部分网站最后一页按钮会置灰禁用) const isDisabled = await page.evaluate(el => el.disabled, nextButton); if (isDisabled) break; // 点击下一页并等待内容加载,若AJAX加载不触发页面跳转,可替换为等待新元素出现 await Promise.all([ nextButton.click(), page.waitForNavigation({ waitUntil: 'networkidle0', timeout: 0 }), // 备选:等待新条目加载完成,比如 page.waitForSelector('.item-container:last-child', { timeout: 0 }) ]); // 可选:添加短暂延迟,模拟人类操作,降低反爬触发概率 await page.waitForTimeout(500); } // 将Set转为数组,方便后续处理 const result = Array.from(allHrefs); console.log(`共抓取到 ${result.length} 条链接`); await browser.close(); return result; } // 调用函数,替换为你的目标网址 scrapeAllHrefs('你的目标网站URL');
关键注意事项:
- 精确选择器:务必把
document.querySelectorAll('a')替换为目标条目容器内的a标签选择器,避免抓取导航栏、页脚等无关重复链接。 - 下一页按钮适配:根据网站实际的下一页按钮CSS选择器修改,比如常见的
.next、#pagination-next等。 - 等待逻辑调整:如果
waitForNavigation不生效(部分网站用AJAX加载不触发页面跳转),换成等待新内容元素出现的逻辑更可靠。 - 反爬应对:添加合理延迟、模拟滚动等操作,避免因频繁请求触发网站反爬机制。
内容的提问来源于stack exchange,提问作者Ria
相关产品推荐
相关产品推荐

