【发布时间】:2019-05-31 06:38:00
【问题描述】:
我有一个节点脚本,它不断地抓取网站列表以获取信息。我想尝试提高脚本的效率;但是,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 个。
【问题讨论】:
-
使用Child Process 或实验性Thread
-
@GetOffMyLawn 两者都完全不适合手头的任务。他的问题是他一次只做一件事。
-
节点一次只能处理一件事,你可以使用
async/await任何你想要的,但它的核心仍然一次只能处理一件事。因此,子进程或线程将处理同步问题。 -
在您的示例代码中,您实际上并没有对结果做任何事情,是因为它被虚拟化了吗?我们在谈论多少个网址?你只是在监控输出吗?
-
@GetOffMyLawn 这里的问题不是服务器受 CPU 限制......问题是他一次只发出一个请求。如果服务器实际上受 CPU 限制,则考虑线程或多进程。同时,简单地同时发出多个请求可以更好地利用系统。
标签: javascript node.js web-scraping