【问题标题】:Limiting number of rows read from a CSV file with async/await function in Node.js在 Node.js 中使用 async/await 函数限制从 CSV 文件读取的行数
【发布时间】:2018-11-06 06:00:53
【问题描述】:

我正在使用 Puppeteer 以使用 async/await 方法抓取网页。

为了抓取数据,我首先要使用网页浏览器搜索 600 多个值,因此我创建了一个包含这些值的 CSV 文件。

我导入 csv-parser 来读取文件,然后在 csv 中的每一行中声明一个字符串,以便以后可以在浏览器中搜索每个字符串的内容。

这是我整理的代码:

const csv = require('csv-parser');
(async function main (){
    try{        
    fs.createReadStream('values.csv')
    .pipe(csv())
    .on('data', async function (data) {
            const str = String(data.Row1)

// … Here’s the code to open headless Chrome and open the webpage (working fine)

// Code to type in the string into the search bar and click the search button:

await page.type('#SearchBar', str);
await page.click('#SearchButton');

// … Here’s the code to scrape the data displayed after each search (working fine)
});
})();

当我运行代码时,它试图打开 600 多个无头浏览器并出现以下消息:

(node:9568) MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。添加了 11 个 SIGHUP 侦听器。使用emitter.setMaxListeners() 增加限制

然后我尝试读取一个只有 10 行的 CSV 文件,它工作正常。但是我需要将所有 600 个值包含到文件中,因此我尝试通过使用 async 模块使函数将回调作为其第二个参数来将搜索次数限制为 10,但它不起作用。

¿如何一次异步搜索 10 个值,即将每次迭代的读取限制为 10 行?

如果我没有足够清楚地提出我的问题,或者如果有更简单的方法可以实现相同的目标,我深表歉意,但我在编码方面的经验为零,我只是在尝试为我父母的办公室开发一个工具我明年离开。

【问题讨论】:

    标签: node.js csv web-scraping puppeteer


    【解决方案1】:

    您需要将启动浏览器的代码移到data 回调之外,并将此逻辑放入finish 回调中。在data 回调中,只需将数据缓冲到一个数组中,您可以稍后slice

    const csv = require('csv-parser');
    (async function main (){
        try{
        var searchTerms = [];        
        fs.createReadStream('values.csv')
        .pipe(csv())
        .on('data', function (data) {
                const str = String(data.Row1)
                searchTerms.push(str);
         })
         .on('finish', function() {
    
    for (var i = 0; i < 10; i++) {
      var searchTermsChunk = searchTerms.slice(i*60, (i+1)*60);
      (async function(searchTermsChunk) {
        searchTermsChunk.forEach(function(str) {
          // … Here’s the code to open headless Chrome and open the webpage (working fine)
    
          // Code to type in the string into the search bar and click the search button:
    
           await page.type('#SearchBar', str);
           await page.click('#SearchButton');
    
          // … Here’s the code to scrape the data displayed after each search (working fine)
        });
      })(searchTermsChunk);
    }
    });
    })();
    

    我没有测试过这段代码,所以它可能无法开箱即用。一般的想法是,在finish 事件处理程序中,您将数据分成10 个块。每个searchTermsChunk 包含 60 个元素(最后一个块可能更小)。对于每个块,您创建一个异步函数,因此总共有 10 个异步函数。在每个异步函数中,您迭代块的元素并等待页面事件的完成。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2019-05-30
      • 2021-08-06
      • 1970-01-01
      • 2021-06-26
      • 2020-07-13
      • 1970-01-01
      • 2017-03-28
      • 2017-12-17
      相关资源
      最近更新 更多