【问题标题】:Nodejs: Comparing results of two async requestsNodejs:比较两个异步请求的结果
【发布时间】:2017-04-06 23:41:08
【问题描述】:

我查看了有关此主题的其他问题,但不知道在这种情况下如何实现它。

我想要达到的目标:

  1. 访问网站并获取内容(正文)
  2. 访问匹配的测试站点并获取内容(正文)
  3. 比较内容
  4. 在 page1 上抓取链接
  5. 在 page2 上抓取链接
  6. 继续

我目前遇到的问题是我无法比较内容,因为请求没有相互等待。 这是我的代码目前的样子。

require('colors');
var request = require('request');
var cheerio = require('cheerio');
var jsdiff = require('diff');
var URL = require('url-parse');

var PROD_START_URL = "https://www.somesite.org";
var MAX_PAGES_TO_VISIT = 100;

var pagesVisited = {};
var numPagesVisited = 0;
var pagesToVisit = [];

var globalProdContent;
var globalTestContent;

var url = new URL(PROD_START_URL);
var baseUrl = url.protocol + "//" + url.hostname;

pagesToVisit.push(PROD_START_URL);
crawl();

function crawl() {
  if(numPagesVisited >= MAX_PAGES_TO_VISIT) {
    console.log("Reached max limit of number of pages to visit.");
    return;
  }
  var nextPage = pagesToVisit.pop();
  if (nextPage in pagesVisited) {
    // We've already visited this page, so repeat the crawl
    crawl();
  } else {
    // New page we haven't visited
    visitPage(nextPage, crawl);
  }
}

function visitPage(url, callback) {
  // Add page to our set
  pagesVisited[url] = true;
  numPagesVisited++;

  // Make the request
  console.log("Visiting page " + url);
  request(url, function(error, response, body) {
     // Check status code (200 is HTTP OK)
     console.log("Status code: " + response.statusCode);
     if(response.statusCode !== 200) {
       callback();
       return;
     }
     // Parse the document body
     var $ = cheerio.load(body);
     globalProdContent = $("#wrapper").text();

     // Build new URL for test site
     var testURL = url.replace("https://www.somesite.org", "http://matching.testsite");

     // Scrape test site
     scrapeTestContent(testURL);


     collectInternalLinks($);
     callback();
  });
}

function collectInternalLinks($) {
    var relativeLinks = [];
    relativeLinks = $("a[href]");

    console.log("Found " + relativeLinks.length + " relative links on page");
    relativeLinks.each(function() {
        pagesToVisit.push(baseUrl + "/" + $(this).attr('href'));
    });
}

function scrapeTestContent(testURL) {
    console.log("Visiting matching testpage " + testURL);
    request(testURL, function(error, response, body) {
        console.log("Status code: " + response.statusCode);
        if(response.statusCode !== 200) {
            callback();
        return;
        }

        var $ = cheerio.load(body);
        globalTestContent = $("#wrapper").text();
        console.log(globalTestContent);

    });
}

有没有更简单的方法可以做到这一点,还是我完全偏离了轨道?

【问题讨论】:

    标签: node.js asynchronous request web-crawler


    【解决方案1】:

    这可以通过两种方式完成: 1. 给scrapeTestContent添加回调

        function scrapeTestContent(testURL, cb) {
            ...
            request(testURL, function(error, response, body) {
                cb();
            });
    
        In visitPage,
    
        function visitPage(url, callback) {
            ...
            scrapeTestContent(testURL, () => collectInternalLinks($));
        }
    
    1. 使用 ES6 承诺。在scrapeTestContent() 中返回new Promise((resolve, reject) => {}。然后在visitPage 中,使用以下构造:scrapeTestContent(testUrl).then(() => collectInternalLinks($))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      相关资源
      最近更新 更多