使用node-fetch获取网页HTML不全,无法通过cheerio提取完整商品链接
你的猜测完全正确,你要抓取的站点是GoDaddy建站工具生成的客户端渲染页面,商品列表数据需要浏览器执行页面内置的JS脚本后才会渲染到DOM中。node-fetch只能获取服务端返回的初始静态HTML,不会执行页面JS,自然拿不到动态生成的商品链接。
方案1:使用无头浏览器模拟页面加载(最稳妥)
用Puppeteer这类支持JS执行的无头浏览器工具,完全模拟浏览器的页面加载流程,等内容渲染完成后再提取数据。
操作步骤:
- 安装依赖:
npm install puppeteer cheerio - 示例代码:
const puppeteer = require('puppeteer'); const cheerio = require('cheerio'); (async () => { // 启动浏览器 const browser = await puppeteer.launch({ headless: 'new' }); const page = await browser.newPage(); // 模拟真实浏览器UA,避免被反爬拦截 await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'); // 访问页面,等待网络请求完成 await page.goto('https://shop.gossmanknives.com/shop?olsPage=products', { waitUntil: 'networkidle2' }); // 等待商品卡片元素渲染完成 await page.waitForSelector('[data-ux="Link"][data-aid^="PRODUCT_NAME_RENDERED_"]'); // 获取页面渲染后的完整HTML const html = await page.content(); const $ = cheerio.load(html); // 提取商品链接 const productLinks = $("a[data-ux='Link'][data-aid^='PRODUCT_NAME_RENDERED_']") .map((i, el) => $(el).attr('href')) .toArray(); console.log(productLinks); await browser.close(); })();
方案2:直接调用商品数据接口(效率更高)
你可以打开浏览器控制台的「网络」标签,筛选「Fetch/XHR」请求,刷新页面后就能找到站点加载商品列表的后端接口,直接请求该接口获取JSON格式的商品数据,不需要解析HTML,效率更高还不容易出问题。
额外注意
如果不想用无头浏览器,也可以先给node-fetch加上完整的浏览器请求头(比如User-Agent、Accept、Cookie等),先确认是不是反爬策略返回了简化版页面,不过客户端渲染的站点仅靠改请求头还是拿不到动态数据,最终还是需要走上面两种方案。
内容的提问来源于stack exchange,提问作者ppedrazzi
相关产品推荐
相关产品推荐

