javascript - 网页抓取时如何提高效率?
问题描述
我有一个节点脚本,它不断地抓取网站列表以获取信息。我想尝试提高脚本的效率;但是,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 个。
解决方案
您现在的代码将等待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
});
推荐阅读
- graph - 使用 Chart.js,如何为多组数据创建条形图
- javascript - 为什么 h1 标签不在移动视图中居中
- javascript - React 限制渲染的数量以防止无限循环 - 反应钩子
- google-app-engine - FLASK - 如何使用 app.config ['PORT'] 配置端口?
- python - 有没有办法在给定两组角索引坐标的情况下提取任意多维 Python 数组的实体框切片?
- python - 即使超级用户确实存在,也无法在 django 管理站点中登录管理员
- nginx - 与 dokku 和 hasura 的“上游过早关闭连接”
- python - 披萨店功能中的循环问题
- javascript - 使用 rxjs 进行弹珠测试时如何暂停和恢复虚拟时间?
- c++ - 运行时错误:未定义符号:_ZN11IO_Expander14channel_selectEih