Node.js使用Axios+Cheerio爬虫后如何导出全部数据为JSON文件
问题原因
- 直接对选中的多组DOM节点调用
.text()方法会自动将所有节点的文本内容拼接为单个字符串,无法拆分出单条商品信息 - 未以商品为单位匹配名称和价格,导致两类数据无法一一对应
- 初始版本的代码在循环中重复调用
fs.writeFile会覆盖之前写入的内容,最终仅保留最后一条数据
修复方案
你需要先定位到每个商品的公共父容器,再在单个父容器内单独提取对应商品的名称和价格,汇总为数组后一次性写入文件,修复后的代码如下:
async getData() { try { const KeyWord = 'laptop' const url = `https://www.amazon.com/s?k=${KeyWord}&ref=nb_sb_noss_2`; // 增加请求头避免亚马逊反爬拦截 const response = await axios.get(url, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } }) const $ = cheerio.load(response.data); // 存储所有商品的数组 const products = [] // 遍历每个搜索结果商品卡片的父容器 $('div[data-component-type="s-search-result"]').each((i, el) => { // 在当前商品容器内单独取名称和价格 const name = $(el).find('span.a-size-medium').text().trim() const price = $(el).find('span.a-offscreen').first().text().trim() // 过滤空数据 if(name && price) { products.push({name, price}) } }) // 一次性写入文件 const dataJsons = JSON.stringify(products, null, 2); await fs.promises.writeFile('./data/data.json', dataJsons) console.log('数据写入成功,共抓取到'+ products.length +'条商品') } catch (error) { console.error('抓取出错:', error); } }
改动说明
- 新增请求头
User-Agent模拟浏览器请求,避免亚马逊反爬机制拦截返回异常内容 - 先定位到每个商品的公共父节点,单个商品内部单独提取信息,保证名称和价格一一对应
- 所有数据存入数组后一次性写入文件,避免循环内重复覆盖文件内容
- 替换回调写法为async/await,代码逻辑更清晰,避免回调嵌套问题
内容的提问来源于stack exchange,提问作者Yurikaza
相关产品推荐
相关产品推荐

