我对 Javascript 和 NodeJs 还很陌生,我只是想知道如何构建它,以便它会生成以下结构的消息:标题和标题。所以我想做的是初始化变量,然后编写一个函数来从网站上抓取数据(scrapData
),然后运行该函数,然后将信息放入数组中(titles、captions、images_long
),则循环将生成带有 title 和 Caption
的消息。我只是对结构和调用函数感到困惑。以下是该命令的代码:
if (message.content.startsWith(prefix + 'latest')) {
//website url variables
var website_domain = "websitedomain.com/";
var website_path = args;
var website_url = website_domain + website_path;
//array for elements scrapped
var titles = [];
var captions = [];
var images_long = [];
//opening url and scrapping elements
function scrapData(website_url) {
request(website_url, function(err, resp, body) {
var $ = cheerio.load(body);
//retrieves titles
$('.title').each(function() {
var title = $(this).children('h2').children('span').text();
titles.push(title);
});
//retrieves captions
$('.post-box-excerpt').each(function() {
var caption = $(this).children('p').text();
captions.push(caption);
});
//retrieves images
$('.thumbnail').each(function() {
var image = $(this).children('img').attr('src');
images_long.push(image);
});
});
}
scrapData(website_url);
//produce embed messages
for (i = 0; i < titles.length; i++) {
const embed = new Discord.RichEmbed()
.setColor('#8E44AD')
.addField(((i + 1) + ". " + titles[i]), captions[i], true);
//set images here
message.channel.send({embed});
}
}
最佳答案
对 scrapData 的调用必须等待请求(即异步)完成才能处理数据。您必须将所有代码放入原始请求的回调中,或者考虑使用 Promises(Promises 将支持 NodeJS 7+ 中良好的 async/await)
将您的 require("request") 更改为 require("request-promise-native") 并执行如下操作:
function scrapData(website_url) {
return request(website_url)
.then(body => {
let items = [],
$ = cheerio.load(body);
$('.post-box').each((index, element) => {
let title = $(element).find('.title h2 span').first().text(),
caption = $(element).find('.post-box-excerpt p').first().text(),
thumbnail = $(element).find('.thumbnail img').first().attr('src');
items.push({ title, caption, thumbnail })
})
return items;
})
}
scrapData(website_url)
.then(items => {
//produce embed messages
for (let i = 0; i < items.length; i++)
{
const embed = new Discord.RichEmbed()
.setColor('#8E44AD')
.addField(((i + 1) + ". " + items[i].title), items[i].caption, true);
//set images here
message.channel.send({ embed });
}
})
我不喜欢您抓取标题、说明文字和缩略图的方式,因为索引可能会不同步。假设您缺少第二个索引的一个标题,那么您将拥有标题 ['title 1', 'title 2', 'title 3'] 和标题,如:['caption 1', 'caption 3']。确保抓取父 block 的标题和说明文字。不确定你如何使用cheerio,但我尽力在示例中做到最好。
注意,一件重要的事情, $('').each(function() { $(this) })
与 $('').each( 不同() => { $(this) })
因为 this 位于不同的范围内。谷歌范围和箭头功能。您可以将我的箭头函数更改为普通函数,或者通过使用每个函数的参数来解决这个问题,例如 $('').each( (index, element) => { $(element) })
关于javascript - NodeJS - 调用函数和结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44816681/