Node.js 节点JS-请求npm-操纵url正文
我正在使用NodeJS进行服务器端(self)项目(这是第一次),遇到了一些困难 我的目标如下: 第一部分-Im在我的服务器中使用“/uploads/processData”URL从用户请求中获取URL 现在我想访问用户请求URL并获取他们的HTML文件,为此我使用“请求”npm包(下面的代码) 第二部分-我希望访问从请求包(第一部分)返回的主体,因此我使用cheerio npm包来实现这一点 现在我的问题是——假设我正在尝试获取url的主体: 由于某些我无法理解的原因(可能是因为缺乏网络开发方面的知识),我并不总是能得到与我使用F12查看上面页面(链接)时看到的相同的正文,以及我的第一部分代码。因此,有时我的cheerio提取(第二部分)会像我预期的那样工作,有时则不会(因为完整/原始HTML文件中的某些元素丢失)。起初我认为这可能是缓存,所以我添加了一个中间件来设置“nocache”标志 我错过了什么?我尝试操作的方式是否错误?有没有办法确保我每次都得到相同的完整/原始HTML 这是到目前为止我的代码- nocache中间件Node.js 节点JS-请求npm-操纵url正文,node.js,cheerio,npm-request,Node.js,Cheerio,Npm Request,我正在使用NodeJS进行服务器端(self)项目(这是第一次),遇到了一些困难 我的目标如下: 第一部分-Im在我的服务器中使用“/uploads/processData”URL从用户请求中获取URL 现在我想访问用户请求URL并获取他们的HTML文件,为此我使用“请求”npm包(下面的代码) 第二部分-我希望访问从请求包(第一部分)返回的主体,因此我使用cheerio npm包来实现这一点 现在我的问题是——假设我正在尝试获取url的主体: 由于某些我无法理解的原因(可能是因为缺乏网络开发
function nocache(req, res, next) {
res.header("Cache-Control", "private, no-cache, no-store, must-revalidate");
res.header("Expires", "-1");
res.header("Pragma", "no-cache");
next();
}
编辑
uploadRoutes.post("/processGoogleSearchData", nocache, (req, res) => {
//Assuming getting in req.body the google result JSON as "googleSearchResult"
var itemsArr = [];
var linksArr = [];
var bodysArr = [];
itemsArr = req.body.googleSearchResult.items;
if (itemsArr.length === 0) {
//return appropriate message
return res.status(400).send({ message: "No data sent to server" });
}
var linksArr = itemsArr.map(item => item.link);
//Get the needed info from every link
linksArr.forEach(link => {
request(link, (err, response, body) => {
if (!err && response.statusCode === 200) {
var $ = cheerio.load(body);
var tr = $(".a-lineitem").children();
var priceTd = tr.find(".a-span12");
var priceSpan = priceTd.find("#priceblock_ourprice");
console.log(priceSpan.text());
//when trying to build array of bodys the extraction doesnt work at all
bodysArr.push(body);
}
});
});
res.send(bodysArr);
});
我将代码改为上面的代码,看起来数据提取工作更频繁。有人能解释为什么提取有时仍然不起作用吗?
出于debbug的目的,我尝试返回bodysArr,但当我这样做时,提取根本不起作用,而且我的路径响应总是空数组,这是为什么?问题在于:
res.send(bodysArr);
在调用之后直接执行
linksArr.forEach(link => {
回调
(err, response, body) => {
if (!err && response.statusCode === 200) {
var $ = cheerio.load(body);
var tr = $(".a-lineitem").children();
var priceTd = tr.find(".a-span12");
var priceSpan = priceTd.find("#priceblock_ourprice");
console.log(priceSpan.text());
//when trying to build array of bodys the extraction doesnt work at all
bodysArr.push(body);
}
还不能保证已经开火了。您需要的是确保res.send(bodysArr)在所有请求发生后运行
有几种方法可以解决这个问题,其中一种是使用优秀的
希望您能通过这个示例了解它的要点
var数组=[1,2,3]
函数asyncRequest(输入、回调){
//在此处执行提取请求,完成后调用回调
setTimeout(callback,10);//以setTiemout为例
}
async.each(数组、asyncRequest,(err)=>{
如果(错误){
犯错误;
}
控制台日志(“全部完成”);
});代码>
在查看了Sudsy解释之后,我遇到了异步方法的循环
在处理此主题时,我无法找出以下代码的错误:
这很好用-因此我最终使用了它
async function getItemsInfo(itemsArr) {
return itemsArr.map(async item => {
try {
var body = await axios(item.link);
var $ = await cheerio.load(body.data);
var tr = await $(".a-lineitem").children();
var priceTd = await tr.find(".a-span12");
var priceSpan = await priceTd.find("#priceblock_ourprice");
return priceSpan.text();
} catch (err) {
return err.message;
}
});
}
getItemsInfo(linksArr)
.then(res => Promise.all(res))
.then(res => console.log(res))
.catch(err => console.error(err));
有人能给我解释一下以下代码有什么问题吗?
async function getItemsInfo(itemsArr) {
await Promise.all(
itemsArr.map(async item => {
try {
var body = await axios(item.link);
var $ = await cheerio.load(body.data);
var tr = await $(".a-lineitem").children();
var priceTd = await tr.find(".a-span12");
var priceSpan = await priceTd.find("#priceblock_ourprice");
return priceSpan.text();
} catch (err) {
throw err.message;
}
})
)
.then(resulst => {
return results;
})
.catch(err => {
throw err.message;
});
}
//the caller function
try {
getItemsInfo(linksArr).then(results => {
res.status(200).send(results);
});
} catch (err) {
res.status(400).send(err.message);
}
或
async function getItemsInfo(itemsArr) {
const promises = itemsArr.map(async item => {
try {
var body = await axios(item.link);
var $ = await cheerio.load(body.data);
var tr = await $(".a-lineitem").children();
var priceTd = await tr.find(".a-span12");
var priceSpan = await priceTd.find("#priceblock_ourprice");
return priceSpan.text();
} catch (err) {
return err.message;
}
});
var results = await Promise.all(promises)
.then(results => {
return results;
})
.catch(err => {
return err.message;
});
}
//the caller function
try {
getItemsInfo(linksArr).then(results => {
res.status(200).send(results);
});
} catch (err) {
res.status(400).send(err.message);
}
谢谢@Sudsy我现在明白我的问题了。