如何用JS存储多产品信息以便后续在其他站点录入?
如何存储Puppeteer批量获取的产品信息以便后续录入
嘿,我看到你尝试用Puppeteer批量抓取产品信息,但目前的代码里有几个小问题导致你没法正确获取和存储数据,我来一步步帮你解决:
首先,你在page.evaluate里用forEach加setTimeout的方式有问题——因为forEach不会等待异步操作完成,而且setTimeout里的return根本没法把数据传递出来,最后resultado会是undefined。我们需要改成用异步循环来逐个点击产品,收集数据,然后再存储到文件里。
接下来,关于存储方式,最适合后续导入另一站点的有两种常用方式:
1. 存储为JSON文件
JSON是结构化格式,容易读取和处理,后续在目标站点录入时可以直接读取JSON数据循环填入。
2. 存储为CSV文件
如果目标站点支持批量导入CSV,这种格式会更方便,很多后台系统都支持直接上传CSV批量录入数据。
修正后的完整代码(以JSON存储为例)
const puppeteer = require('puppeteer'); const fs = require('fs-extra'); // 记得替换成你的账号密码 const user = '你的邮箱'; const password = '你的密码'; (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.goto('https://www.wavenfe.com.br/'); // 登录 await page.type('#logarEmail', user, { delay: 100 }); await page.type('#logarSenha', password, { delay: 100 }); await page.click('#logar'); // 这里最好用await,确保点击完成 // 导航到产品页面 await page.waitForSelector('#container > div.menu_servicos > div > div.box_menu_servicos > h2 > a'); await page.click('#container > div.menu_servicos > div > div.box_menu_servicos > h2 > a'); await page.waitForSelector('#produto'); await page.click('#produto'); // 获取所有产品链接的元素 const productLinks = await page.$$('tbody > tr > td:nth-child(1) > span > a'); const productList = []; // 用for循环逐个处理,确保异步操作顺序执行 for (let i = 0; i < productLinks.length; i++) { // 点击当前产品链接 await productLinks[i].click(); // 等待产品详情加载完成(这里最好等具体的输入框出现) await page.waitForSelector('#txtProdCodigo'); // 获取产品信息 const productInfo = await page.evaluate(() => { return { codigoProduto: document.querySelector("#txtProdCodigo").value, descricaoProduto: document.querySelector("#txtProdDesc").value }; }); productList.push(productInfo); console.log(`已收集第${i+1}个产品信息:`, productInfo); // 返回产品列表页面,准备点击下一个 await page.goBack(); // 重新获取产品链接(因为页面返回后元素可能失效) await page.waitForSelector('tbody > tr > td:nth-child(1) > span > a'); productLinks[i+1] = await page.$(`tbody > tr:nth-child(${i+2}) > td:nth-child(1) > span > a`); } // 将数据写入JSON文件 await fs.writeJson('./produtos.json', productList, { spaces: 2 }); console.log('所有产品信息已保存到produtos.json'); // 如果需要CSV格式,可以用csv-writer包,先安装npm install csv-writer // const createCsvWriter = require('csv-writer').createObjectCsvWriter; // const csvWriter = createCsvWriter({ // path: './produtos.csv', // header: [ // {id: 'codigoProduto', title: 'CODIGO_PRODUTO'}, // {id: 'descricaoProduto', title: 'DESCRICAO_PRODUTO'} // ] // }); // await csvWriter.writeRecords(productList); // console.log('所有产品信息已保存到produtos.csv'); await browser.close(); })();
关键改进点:
- 用
for循环替代forEach+setTimeout,确保每个产品的点击、获取、返回操作按顺序完成,不会出现异步混乱。 - 每次返回列表页面后重新获取下一个产品链接,避免页面跳转后之前的DOM元素失效。
- 使用
fs-extra的writeJson方法(和原生fs的writeFile类似,但更简洁)将数据写入本地JSON文件,后续可以直接读取这个文件在目标站点录入。
后续录入目标站点的思路:
当你需要在目标站点录入时,可以再写一个Puppeteer脚本:
- 读取
produtos.json里的数据。 - 打开目标站点,登录。
- 循环遍历productList,逐个填入表单提交即可。
这样批量抓取和批量录入就都完成啦,适合产品数量多的场景。
内容的提问来源于stack exchange,提问作者Matheus Nascimento
相关产品推荐
相关产品推荐

