节点js请求和cheerio等待页面完全加载

时间:2017-10-05 22:45:36

标签: javascript node.js request

我试图从页面上抓取图像但页面返回占位符源attr,如果该页面没有完全加载,(完全加载大约需要0.5秒)我将如何进行请求等待?

尝试着做

function findCommonMovies(movie, callback){

    request('http://www.imdb.com/find?ref_=nv_sr_fn&q='+ movie +'&s=all', function (error, response, body) {
      if (error){
          return
      }else{
          var $ = cheerio.load(body);
          var title = $(".result_text").first().text().split("(")[0].split(" ").join('')
          var commonMovies = []
          // var endurl = $("a[name=tt] .result_text a").attr("href")
          var endurl = $('a[name=tt]').parent().parent().find(".findSection .findList .findResult .result_text a").attr("href");


          request('http://www.imdb.com' + endurl, function (err, response, body) {

              if (err){
                  console.log(err)
              }else{

                  setInterval(function(){var $ = cheerio.load(body)}, 2000)

                  $(".rec_page .rec_item a img").each(function(){


                    var title = $(this).attr("title")
                    var image = $(this).attr("src")

                    commonMovies.push({title: title, image: image})
                  });
              }
              callback(commonMovies)
          });
      }
    });

}
findCommonMovies("Gotham", function(common){
  console.log(common)
})

4 个答案:

答案 0 :(得分:1)

Cheerio不是网络浏览器。它只是HTML的解析器。这意味着没有执行异步请求的javascript函数。

因此。除非您使用充当Web浏览器的内容,否则您无法执行所需操作。例如,Selenium会向许多网络浏览器添加API。

您需要下载Selenium客户端并继续运行它,只要您想继续向异步内容加载的网站发出请求。

此外,您将需要一个基于您正在使用的语言和所需Web驱动程序的包装器。 webdriver用于添加对不同Web浏览器的支持。

我假设你正在使用NodeJS或基于js的类似东西,here you go.

请务必查看API.

希望得到一些帮助。

您还可以查看PhantomJS.

答案 1 :(得分:0)

setTimeout(函数,等待的毫秒数)将暂停所需的秒数。 setTimeout(function(){var $ = cheerio.load(body)},2000)

答案 2 :(得分:0)

在我看来,你的回调位于错误的地方,不需要任何计时器。当request()调用其回调时,整个响应都已就绪,因此不需要计时器。

这里带有回调的代码在正确的位置,并且也进行了更改,以便它有一个错误参数,以便调用者可以传播并检测错误:

function findCommonMovies(movie, callback){
    request('http://www.imdb.com/find?ref_=nv_sr_fn&q='+ movie +'&s=all', function (error, response, body) {
      if (error) {
          callback(error);
          return;
      } else {
          var $ = cheerio.load(body);
          var title = $(".result_text").first().text().split("(")[0].split(" ").join('')
          var commonMovies = [];
          // var endurl = $("a[name=tt] .result_text a").attr("href")
          var endurl = $('a[name=tt]').parent().parent().find(".findSection .findList .findResult .result_text a").attr("href");
          request('http://www.imdb.com' + endurl, function (err, response, body) {
              if (err) {
                  console.log(err)
                  callback(err); 
              } else {
                  var $ = cheerio.load(body);
                  $(".rec_page .rec_item a img").each(function(){
                    var title = $(this).attr("title");
                    var image = $(this).attr("src");
                    commonMovies.push({title, image});
                  });
                  callback(null, commonMovies);
              }
          });
       }
    });
}

findCommonMovies("Gotham", function(err, common) {
  if (err) {
     console.log(err);
  } else {
     console.log(common)
  }
});

注意:这将仅访问服务器为您请求的URL提供的HTML标记。如果这些页面具有由浏览器Javascript插入的内容,则该内容将不会出现在您所获得的内容中,并且不会出现任何延迟。那是因为cheerio不运行浏览器Javascript,它必须解析服务器最初发送的HTML。要运行浏览器Javascript,您需要一个比cheerio提供的更完整的浏览器引擎,例如PhantomJS,它将实际运行该页面的Javascript。

答案 3 :(得分:0)

您可以设置超时时间:

var options = {
    url : 'http://www.imdb.com/find?ref_=nv_sr_fn&q='+ movie +'&s=all',
    timeout: 10000 //set waiting time till 10 minutes.
  }
  request(options, function(err, response, body){
    if (err) {
      console.log(err);
    }
   //do what you want here
}