React 和 MongoDB Stitch App 中的网页抓取
Web Scraping in React & MongoDB Stitch App
我正在将一个 MERN 项目转移到 React + MongoDB Stitch 中,因为它允许轻松的用户身份验证、快速部署等。
但是,我很难理解在哪里以及如何调用网站抓取功能。以前,我在 Express.js 中用 cheerio 进行了网络抓取,例如:
app.post("/api/getTitleAtURL", (req, res) => {
if (req.body.url) {
request(req.body.url, function(error, response, body) {
if (!error && response.statusCode == 200) {
const $ = cheerio.load(body);
const webpageTitle = $("title").text();
const metaDescription = $("meta[name=description]").attr("content");
const webpage = {
title: webpageTitle,
metaDescription: metaDescription
};
res.send(webpage);
} else {
res.status(400).send({ message: "THIS IS AN ERROR" });
}
});
}
});
但显然使用 Stitch 不需要 Node & Express。有没有一种方法可以获取另一个站点的内容,而不必托管仅提供该功能的 node.js 应用程序?
谢谢
事实证明,您可以在 MongoDB Stitch 中构建函数,从而允许您上传外部依赖项。
但是,也有限制,例如,当 request 起作用时,cheerio 不能作为上传的外部依赖项起作用。因此,一个解决方案是在 AWS 的 lambda 中创建一个无服务器函数,然后将 mongoDB stitch 连接到 AWS lambda(mongoDB stitch 可以连接到许多第三方服务,包括许多 AWS lambda 云服务,例如lambda、s3、kinesis 等)。
AWS lambda 允许您上传任何外部依赖项,如果 mongoDB stitch 允许,我们就不需要 lambda,但 stitch 仍然需要很多支持。在我的例子中,我有一个带有 cheerio 和 request 作为外部依赖项的节点函数,将其上传到 lambda:创建一个帐户,创建新的 lambda 函数,并将您的节点模块和代码打包到一个 zip 文件中以上传它。您的 zip 应如下所示:
包含该函数的文件应如下所示:
const cheerio = require("cheerio");
const request = require("request");
exports.rss = function(event, context, callback) {
request(event.requestURL, function(error, response, body) {
if (!error && response.statusCode == 200) {
const $ = cheerio.load(body);
const webpageTitle = $("title").text();
const metaDescription = $("meta[name=description]").attr("content");
const webpage = {
title: webpageTitle,
metaDescription: metaDescription
};
callback(null, webpage);
return webpage;
} else {
callback(null, {message: "THIS IS AN ERROR"})
return {message: "THIS IS AN ERROR"};
}
});
};
然后在 mongoDB 中,连接到第三方服务,选择 AWS,输入您通过创建 IAM 亚马逊用户获得的密钥。在规则 -> 操作中,选择 lambda 作为您的 API,并允许所有操作。现在,在您的 mongoDB 拼接函数中,您可以连接到 Lambda,在我的例子中该函数应该如下所示:
exports = async function(requestURL) {
const lambda = context.services.get('getTitleAtURL').lambda("us-east-1");
const result = await lambda.Invoke({
FunctionName: "getTitleAtURL",
Payload: JSON.stringify({requestURL: requestURL})
});
console.log(result.Payload.text());
return EJSON.parse(result.Payload.text());
};
注意:虽然这会大大降低性能,但通常需要两倍的额外时间才能完成调用。
我正在将一个 MERN 项目转移到 React + MongoDB Stitch 中,因为它允许轻松的用户身份验证、快速部署等。
但是,我很难理解在哪里以及如何调用网站抓取功能。以前,我在 Express.js 中用 cheerio 进行了网络抓取,例如:
app.post("/api/getTitleAtURL", (req, res) => {
if (req.body.url) {
request(req.body.url, function(error, response, body) {
if (!error && response.statusCode == 200) {
const $ = cheerio.load(body);
const webpageTitle = $("title").text();
const metaDescription = $("meta[name=description]").attr("content");
const webpage = {
title: webpageTitle,
metaDescription: metaDescription
};
res.send(webpage);
} else {
res.status(400).send({ message: "THIS IS AN ERROR" });
}
});
}
});
但显然使用 Stitch 不需要 Node & Express。有没有一种方法可以获取另一个站点的内容,而不必托管仅提供该功能的 node.js 应用程序?
谢谢
事实证明,您可以在 MongoDB Stitch 中构建函数,从而允许您上传外部依赖项。
但是,也有限制,例如,当 request 起作用时,cheerio 不能作为上传的外部依赖项起作用。因此,一个解决方案是在 AWS 的 lambda 中创建一个无服务器函数,然后将 mongoDB stitch 连接到 AWS lambda(mongoDB stitch 可以连接到许多第三方服务,包括许多 AWS lambda 云服务,例如lambda、s3、kinesis 等)。
AWS lambda 允许您上传任何外部依赖项,如果 mongoDB stitch 允许,我们就不需要 lambda,但 stitch 仍然需要很多支持。在我的例子中,我有一个带有 cheerio 和 request 作为外部依赖项的节点函数,将其上传到 lambda:创建一个帐户,创建新的 lambda 函数,并将您的节点模块和代码打包到一个 zip 文件中以上传它。您的 zip 应如下所示:
包含该函数的文件应如下所示:
const cheerio = require("cheerio");
const request = require("request");
exports.rss = function(event, context, callback) {
request(event.requestURL, function(error, response, body) {
if (!error && response.statusCode == 200) {
const $ = cheerio.load(body);
const webpageTitle = $("title").text();
const metaDescription = $("meta[name=description]").attr("content");
const webpage = {
title: webpageTitle,
metaDescription: metaDescription
};
callback(null, webpage);
return webpage;
} else {
callback(null, {message: "THIS IS AN ERROR"})
return {message: "THIS IS AN ERROR"};
}
});
};
然后在 mongoDB 中,连接到第三方服务,选择 AWS,输入您通过创建 IAM 亚马逊用户获得的密钥。在规则 -> 操作中,选择 lambda 作为您的 API,并允许所有操作。现在,在您的 mongoDB 拼接函数中,您可以连接到 Lambda,在我的例子中该函数应该如下所示:
exports = async function(requestURL) {
const lambda = context.services.get('getTitleAtURL').lambda("us-east-1");
const result = await lambda.Invoke({
FunctionName: "getTitleAtURL",
Payload: JSON.stringify({requestURL: requestURL})
});
console.log(result.Payload.text());
return EJSON.parse(result.Payload.text());
};
注意:虽然这会大大降低性能,但通常需要两倍的额外时间才能完成调用。