【问题标题】:NODE JS - request npm - manipulate url bodyNODE JS - 请求 npm - 操作 url 正文
【发布时间】:2018-08-23 21:21:30
【问题描述】:

我正在使用node js(第一次)在服务器端(self)项目上工作,我遇到了一些困难。

我的目标如下:

第一部分 - 我在我的服务器中使用“/uploads/processData” URL 从用户请求中获取 URL。

现在我想访问用户请求 URL 并获取他们的 HTML 文件,为此我使用“请求”npm 包(代码如下)。

第二部分 - 我想访问我从请求包(从第一部分)返回的正文,所以我使用cheerio npm 包来执行此操作。

现在我的问题 - 假设我正在尝试获取 url 的正文:

https://www.amazon.com/NIKE-Mens-Lunarconverge-Running-Shoes/dp/B06VVFGZHL?pd_rd_wg=6humg&pd_rd_r=61904ea4-c78e-43b6-8b8d-6b5ee8417541&pd_rd_w=Tue7n&ref_=pd_gw_simh&pf_rd_r=VGMA24803GJEV6DY7458&pf_rd_p=a670abbe-a1ba-52d3-b360-3badcefeb448&th=1

出于某种我无法理解的原因(可能是因为缺乏网络开发知识),我没有总是得到与使用 F12 查看上述页面(链接)时看到的相同的正文,以及我的第一部分代码。因此,有时我的 Cheerio 提取(第二部分)按我的预期工作,有时却没有(因为缺少完整/原始 HTML 文件中的某些元素)。一开始我以为可能是缓存的东西,所以我添加了一个中间件来设置“nocache”标志。

我在这里缺少什么?我尝试操作的方式是否错误?有什么方法可以确保我每次都获得相同的完整/原始 HTML?

到目前为止,这是我的代码 - 无缓存中间件

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);
});

我将代码更改为上述代码,似乎数据提取工作更频繁。谁能解释为什么提取有时仍然不起作用? 我尝试 return bodysArr 用于调试目的,但是当我这样做时,提取根本不起作用,我的路径响应始终是一个空数组,这是为什么呢?

【问题讨论】:

    标签: node.js cheerio npm-request


    【解决方案1】:

    问题是:

    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) 在所有请求发生后运行

    有几种方法可以解决这个问题,一种是优秀的async library

    希望你能通过这个例子了解它的要点。

    var array = [1,2,3]
    
    function asyncRequest(input, callback){
      //Do your fetch request here and call callback when done
      setTimeout(callback, 10); //using setTiemout as an example
    }
    
    
    async.each(array, asyncRequest, (err) => {
      if(err){
        throw err;
      }
      console.log("All Finished");
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/async/2.6.1/async.min.js"></script>

    【讨论】:

    • 谢谢@Sudsy 我现在明白我的问题了。
    【解决方案2】:

    在查看了 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);
              }
    

    【讨论】:

      猜你喜欢
      • 2022-08-06
      • 1970-01-01
      • 2020-11-29
      • 1970-01-01
      • 2018-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多