javascript - NodeJS - 调用函数和结构

标签 javascript node.js web-scraping discord

我对 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/

相关文章:

javascript - “Read More” 描述默认不隐藏,只有点击按钮后才隐藏

javascript - 使用 javascript DOM 遍历表

node.js - 插入到另一个有关系的表中

javascript - Express 中的嵌套 api 端点

python - 使用 Python 和 Beautiful Soup 解析 HTML

python - 从指定id的div开始获取嵌套的div内容

javascript - 在另一个 jquery 事件完成后播放声音

javascript - 使用 Axios (React) 从 API 获取数据时出现“Access-Control-Allow-Origin”错误

JavaScript 全局启用异步

python - 跨 <div> 的数据抓取