NodeJS - 调用函数和结构

NodeJS - calling functions and structure

我是 Javascript 和 NodeJs 的新手,我只是想知道我将如何构建它,以便它会产生以下结构的消息:标题和标题。所以我要做的是初始化变量,然后编写一个函数来从网站 (scrapData) 中抓取数据,然后该函数将是 运行 然后将信息放入数组 ( titles, captions, images_long),则循环将生成带有 title and 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+ 中的 nice 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']。确保抓取 parent 块的标题和标题。不确定您是如何使用 cheerio 的,但我已尽力在示例中做到最好。

注意,一件重要的事情,$('').each(function() { $(this) })$('').each(() => { $(this) }) 不同,因为它们在不同的范围内。 Google 作用域和箭头函数。您可以将我的箭头函数更改为普通函数或使用每个函数的参数解决此问题,例如 $('').each( (index, element) => { $(element) })

我建议你使用Crawler Package Nodejs

对我来说效果很好。

并使用 Async 处理异步 JavaScript