使用Cheerio爬取页面时如何获取全部子元素而非仅前若干个?
爬取动态加载内容的解决方法
问题核心原因
你当前使用的axios + cheerio组合仅能抓取服务端首次返回的静态HTML内容,无法处理页面加载完成后JS异步渲染的剩余内容,因此只能拿到初始的8条数据。
解决方案1:使用无头浏览器模拟真实页面加载(Puppeteer)
这种方案直接模拟浏览器打开页面的完整流程,等待动态内容加载完成后再提取数据,兼容性最强。
- 第一步:安装依赖
npm install puppeteer
- 第二步:修改后的代码示例
const express = require('express'); const puppeteer = require('puppeteer'); const cheerio = require('cheerio'); const app = express(); async function getGigObjects(proURL) { try { // 启动无头浏览器 const browser = await puppeteer.launch({ headless: "new" }); const page = await browser.newPage(); // 设置UA await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Edg/94.0.992.38"); // 跳转目标页面 await page.goto(proURL); // 等待1.5秒,保证所有动态内容加载完成(比站点的1秒延迟多预留0.5秒) await page.waitForTimeout(1500); // 获取页面完整渲染后的HTML const pageContent = await page.content(); await browser.close(); let $ = cheerio.load(pageContent) const queryDa = '#perseus-app > div > div > div.layout-row.content-row > div > div > div > div' const gigContainerData = [] $(queryDa).each((parentIdx, parentElem) => { $(parentElem).children().children().children('.text-display-7').children().each((childIdx, childElem) => { const title = $(childElem).text() console.log(title) // 原代码漏了往数组里加数据,这里补上 gigContainerData.push(title) }) }) return gigContainerData } catch (err) { console.log(err) return [] } } app.get('/home', async function (req, res) { const getGigData = await getGigObjects('https://www.fiverr.com/categories/programming-tech/wordpress-services') console.log('Inside Home Login'); res.writeHead(200, { 'Content-Type': 'application/json', }); res.end(JSON.stringify(getGigData)); }); app.listen(3001, () => { console.log('Server Listening on port 3001'); });
解决方案2:直接抓取动态数据接口(效率更高)
这种方案不需要启动浏览器,运行速度更快、资源占用更低:
- 打开浏览器F12开发者工具,切换到「网络」标签,筛选「Fetch/XHR」请求
- 刷新页面,观察页面加载完成1秒左右触发的请求,找到返回gig列表数据的接口
- 直接用axios模拟请求该接口,拿到的是结构化JSON数据,无需解析HTML即可直接提取所有标题
注意事项
- 原代码中定义了
gigContainerData数组但没有做数据插入操作,即使静态内容爬取成功也会返回空数组,上面的示例代码已经修复了该问题 - 频繁爬取站点可能会触发反爬机制,建议合理控制请求频率
内容的提问来源于stack exchange,提问作者AnikBhaya
相关产品推荐
相关产品推荐

