如何在抓取网页时提高效率?

时间:2019-05-30 21:16:28

标签: javascript node.js web-scraping

我有一个节点脚本,该脚本不断抓取网站列表以获取信息。我想尝试提高脚本的效率;但是,nodejs a是单线程运行时。但是在后台,nodejs是多线程的,以允许异步代码。有没有办法利用这一点来提高效率?如果没有,替代方案?

现在,脚本同步运行。我已经尝试过混合使用同步代码和异步代码,但是我总是精疲力尽。示例代码不包含用于刮擦数据或检查数据的逻辑,因为它与逻辑无关。

const request = require('request-promise');
const cheerio = require('cheerio');

const siteList = require('./websites.json');

async function scrapePage(link)
{
    let $, data = {};

    $ = await request({
        uri: link,
        transform: (body) => { return cheerio.load(body) },
        connection : 'keep-alive',
    });

    // Scrape data using cheerio

    return data;
}

async function scrapePages()
{
    for(let site of siteList)
    {
        let data = await scrapePage(site.url);

        // Check data for favored result
    }

    // Tail call to reuse stack space
    return scrapePages();
}

scrapePages();

对于质疑抓取范围的个人,网站列表少于100个。

1 个答案:

答案 0 :(得分:0)

您的代码现在将等待scrapePage()完成:

let data = await scrapePage(site.url);

如果您想一次抓取多个页面,请更改for循环的工作方式。例如,在数组上使用.forEach()

要轻松控制并发操作的数量,请考虑使用await-semaphore之类的软件包。

https://www.npmjs.com/package/await-semaphore

然后,您可以执行以下操作...

import {Semaphore} from 'await-semaphore';
const semaphore = new Semaphore(10); // 10 operations at a time

// Then, inside a loop...
semaphore.use(() => {
  // do your work here
});