javascript - 使用 Cheerio 对象制作 For 循环的正确方法是什么?

标签 javascript node.js express axios cheerio

简单地说,我从网站上抓取数据并将其存储在数据库中。

相关字段是链接、名称、价格和项目条件。

我现在处理这个问题的方法是遍历每个元素并将它们推送到各自的列表中。然后使用 For 循环将其添加到数据库中。所以,例如:

var names= [];
$(".midbox .framebox .frameboxcells .displaybox .displayboxbottom .dt.bg0 .serptablecell2-adv .serptablebasestyle2 .valtitle.lovewrap.padr4 .underlinedlinks").each(function(){
            names.push($(this).text());
        });
...
for (x in names){
                var sql = "REPLACE INTO `item` (`link`, `title`, `price`, `date`, `item_condition`, `country`) VALUES (?)";
                var values = [links[x], names[x], prices[x], '', states[x], cc];
            
                con.query(sql, [values], function(err, result){
                    if (err) throw err;
                    });
            }

这是非常天真的,因为它希望所有元素都存在并且它们完美对齐,到目前为止效果很好,直到我注意到我正在抓取的网站上的一些列表没有 Item Condition 元素,所以它被跳过并且列表不同步,导致错误的值被配对。

我知道我正在寻找的答案与 .each 函数有关,但我不确定如何去做。我想我必须到达最高点,它是 .midbox .framebox .frameboxcells .displaybox .displayboxbottom .dt.bg0 .serptablecell2-adv .serptablebasestyle2 然后从那里开始。如果找不到元素,则添加 NULL 值。

下面是完整的(相关的)代码:

const $ = c.load(response.data);

        $(".midbox .framebox .frameboxcells .displaybox .displayboxbottom .dt.bg0 .serptablecell2-adv .serptablebasestyle2 .splittable .splittablecell1 .padr2.bhserp-txt1.bhserp-new1").each(function(){
            var fixedStr = $(this).text().replace(/,|£|\$|\s|[(GBP)]|[(USD)]/g, '');
            prices.push(Number(fixedStr));
        });

        $(".midbox .framebox .frameboxcells .displaybox .displayboxbottom .dt.bg0 .serptablecell2-adv .serptablebasestyle2 .valtitle.lovewrap.padr4 .underlinedlinks").each(function(){
            names.push($(this).text());
        });

        $(".midbox .framebox .frameboxcells .displaybox .displayboxbottom .dt.bg0 .serptablecell2-adv .serptablebasestyle2 .splittable .splittablecell1.bhserp-txt1 .padl1.labinfo").each(function(){
            if ($(this)){
                states.push($(this).text());
            }
            else{
                console.log("Mistake here, pick me up!"); // I understand what I'm doing here does not make sense and is wrong as I've stated, but since that's what made me realize what I needed to do, I'm leaving it.
                states.push("None");
            }
        });

        $(".midbox .framebox .frameboxcells .displaybox .displayboxbottom .dt.bg0 .serptablecell2-adv .serptablebasestyle2 .valtitle.lovewrap.padr4 .underlinedlinks").each(function(){
            var tempLink = $(this).attr('href');
            var fixedLinks = tempLink.split("=");
            var fixedLinks = fixedLinks[1].split("&");
            links.push("https://www.ebay.co.uk/itm/" + fixedLinks[0]);
        });
...
con.connect(function(err){
            if (err) throw err;
            console.log("Connected!");
            for (x in names){
                var sql = "REPLACE INTO `item` (`link`, `title`, `price`, `date`, `item_condition`, `country`) VALUES (?)";
                var values = [links[x], names[x], prices[x], '', states[x], cc];
            
                con.query(sql, [values], function(err, result){
                    if (err) throw err;
                    });
            }
        });

最佳答案

您应该迭代元素。如果您尝试从链接中单独获取价格,您将获得糟糕的体验。像这样的东西:

for(let div of $('.product').get()){
  let item = {
    link: $(div).find('a').attr('href')
    price: $(div).find('.price').text(),
  }
  // insert item into the db
}

关于javascript - 使用 Cheerio 对象制作 For 循环的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71358654/

相关文章:

javascript - 从 NodeJS 发送数据而不重新渲染整个页面?

ruby-on-rails - Ruby on rails 和 Node.js

javascript - 如何将 collection_select 中的值传递到 Rails 中的 onchange 函数?

javascript - 如何使用 JavaScript 声明和初始化带有键/值的数组,然后动态创建选择下拉列表

javascript - JavaScript 的最后一次重大修订是什么时候?

javascript - 我如何将菜单放在 Bootstrap 面板的左侧?

node.js - 使用 Node JS 和 Mongodb 创建 Hashtag 系统

node.js - expressjs 在模块中修改/添加对象属性

javascript - 仅从 Express 静态目录提供 .js 文件?

javascript - DOM 元素的 InnerHTML 属性已更改,但未渲染