使用Puppeteer爬取加密货币表格所有链接仅获前15个的问题求助
问题原因及解决方案
你的爬虫只拿到前15个链接,核心原因是CoinMarketCap的表格采用了懒加载机制——页面初始只会渲染视口内的行,剩下的内容需要滚动页面后才会逐步加载到DOM中,你的代码在页面刚加载就直接抓取,自然只能拿到已经渲染好的少量行。
另外,你用的选择器里包含动态生成的类名(比如sc-16r8icm-0.escjiH),这类类名是前端框架自动生成的,可能会随时变化,导致选择器失效,建议改用更稳定的定位方式。
修改后的代码
async function run () { try { const browser = await puppeteer.launch({headless: false, defaultViewport: null, args: ['--start-maximized']}); const page = await browser.newPage(); await page.goto("https://coinmarketcap.com/", { waitUntil: 'networkidle2' }); // 等待网络请求稳定 // 等待表格加载完成 await page.waitForSelector('table.cmc-table tbody tr'); // 循环滚动页面,加载所有懒加载的行 let previousHeight; do { previousHeight = await page.evaluate('document.body.scrollHeight'); // 滚动到页面底部 await page.evaluate('window.scrollTo(0, document.body.scrollHeight)'); // 等待新内容加载,可根据页面速度调整等待时间 await page.waitForTimeout(1000); } while (await page.evaluate('document.body.scrollHeight') > previousHeight); // 用更稳定的选择器抓取链接:定位表格第3列(加密货币名称列)的a标签 const grabedTableLinks = await page.evaluate(() => { const aTags = Array.from(document.querySelectorAll('table.cmc-table tbody tr td:nth-child(3) a.cmc-link')); return aTags.map(a => ({ href: a.getAttribute('href') })); }); console.log(grabedTableLinks); await browser.close(); // 避免资源泄漏 return grabedTableLinks; } catch (e) { console.error(e); return e; } } run().catch(console.error);
关键改动说明
- 增加
waitUntil: 'networkidle2':确保页面主要资源加载完成后再执行后续操作 - 循环滚动加载:通过反复滚动到底部并等待,触发懒加载机制,直到所有行都渲染到DOM中
- 替换选择器:使用
td:nth-child(3)定位名称列,避开易变的动态类名,提升代码稳定性 - 补充浏览器关闭操作:防止长期运行导致的资源占用问题
内容的提问来源于stack exchange,提问作者jamesc
相关产品推荐
相关产品推荐

