如何让 node.js 网络爬虫定期检查端点的数据更新?
How to make a node.js webscraper periodically check an endpoint for data updates?
我正在编写一个从第三方聚合数据的 discord 机器人 API。
有一个来自 discord.js
的设计模式,我想将其用于我的网络抓取功能,其中实例化一个客户端对象,并在客户端发出特定事件时执行操作,like so:
const Discord = require('discord.js');
const client = new Discord.Client();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('message', msg => {
if (msg.content === 'ping') {
msg.reply('Pong!');
}
});
client.login('token');
据我了解,此代码将 运行 无限期地执行操作,每次发出特定事件时,例如ready
或 message
.
我无法了解此类功能是如何实现的。更具体地说,我无法弄清楚 discord client
对象如何不断查找更改,并在注意到它们时发出事件。
我想效仿这种设计模式的原因是我可以 运行 一个 node.js 应用程序,它会每隔 10 分钟联系 API 并查看如果有新的信息,有变化就记录到数据库中。
我最初的想法是这样的,但它会因内存不足错误而炸毁调用堆栈。
const events = require("events");
class ScrapeEmitter extends events.EventEmitter {}
const scrapeEmitter = new ScrapeEmitter();
scrapeEmitter.on("timeExpired", () => console.log("call scraping code here"));
while (true) {
setTimeout(() => scrapeEmitter.emit("timeExpired"), 1500);
}
最终目标是,从 index.js
开始,编写以下内容,让它既监听 discord 事件,又抓取数据。
import * as scraper from "./core/scraper";
const Discord = require('discord.js');
const client = new Discord.Client();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('message', msg => {
if (msg.content === 'ping') {
msg.reply('Pong!');
}
});
client.login('token');
scraper.begin_scraping();
这部分代码
while (true) {
setTimeout(() => scrapeEmitter.emit("timeExpired"), 1500);
}
创建无限量的超时。你需要做的是仅在前一个完成后开始超时。一个例子是:
function loop() {
setTimeout(loop, 1500);
}
这将在 1500 秒后调用该函数,该函数将在 1500 秒后调用该函数,依此类推。
但是,更好的解决方案是使用setInterval()
。它看起来像这样:
function loop() {};
setInterval(loop, 1500);
所以,而不是写作
while (true) {
setTimeout(() => scrapeEmitter.emit("timeExpired"), 1500);
}
写入
setInterval(() => scrapeEmitter.emit("timeExpired"), 1500);
这消除了无限循环并按预期运行。
我只是将@Worthy Alpaca 的回答翻译成评论。这是一个社区维基,所以我没有声誉
我正在编写一个从第三方聚合数据的 discord 机器人 API。
有一个来自 discord.js
的设计模式,我想将其用于我的网络抓取功能,其中实例化一个客户端对象,并在客户端发出特定事件时执行操作,like so:
const Discord = require('discord.js');
const client = new Discord.Client();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('message', msg => {
if (msg.content === 'ping') {
msg.reply('Pong!');
}
});
client.login('token');
据我了解,此代码将 运行 无限期地执行操作,每次发出特定事件时,例如ready
或 message
.
我无法了解此类功能是如何实现的。更具体地说,我无法弄清楚 discord client
对象如何不断查找更改,并在注意到它们时发出事件。
我想效仿这种设计模式的原因是我可以 运行 一个 node.js 应用程序,它会每隔 10 分钟联系 API 并查看如果有新的信息,有变化就记录到数据库中。
我最初的想法是这样的,但它会因内存不足错误而炸毁调用堆栈。
const events = require("events");
class ScrapeEmitter extends events.EventEmitter {}
const scrapeEmitter = new ScrapeEmitter();
scrapeEmitter.on("timeExpired", () => console.log("call scraping code here"));
while (true) {
setTimeout(() => scrapeEmitter.emit("timeExpired"), 1500);
}
最终目标是,从 index.js
开始,编写以下内容,让它既监听 discord 事件,又抓取数据。
import * as scraper from "./core/scraper";
const Discord = require('discord.js');
const client = new Discord.Client();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('message', msg => {
if (msg.content === 'ping') {
msg.reply('Pong!');
}
});
client.login('token');
scraper.begin_scraping();
这部分代码
while (true) {
setTimeout(() => scrapeEmitter.emit("timeExpired"), 1500);
}
创建无限量的超时。你需要做的是仅在前一个完成后开始超时。一个例子是:
function loop() {
setTimeout(loop, 1500);
}
这将在 1500 秒后调用该函数,该函数将在 1500 秒后调用该函数,依此类推。
但是,更好的解决方案是使用setInterval()
。它看起来像这样:
function loop() {};
setInterval(loop, 1500);
所以,而不是写作
while (true) {
setTimeout(() => scrapeEmitter.emit("timeExpired"), 1500);
}
写入
setInterval(() => scrapeEmitter.emit("timeExpired"), 1500);
这消除了无限循环并按预期运行。
我只是将@Worthy Alpaca 的回答翻译成评论。这是一个社区维基,所以我没有声誉