【问题标题】:JavaScript scope/code iteration out of syncJavaScript 范围/代码迭代不同步
【发布时间】:2014-11-26 05:28:56
【问题描述】:

我正在尝试创建一个工具来从网页上抓取信息(是的,我有权限)。

到目前为止,我一直在使用 Node.js 和 requests 和 Cheerio 来拉取页面,然后根据 CSS 选择器查找信息。我已经做了足够多的调试,知道脚本肯定是成功地从页面获取信息。

似乎正在发生的情况是,for 循环之后的代码首先执行,或者在调用之后执行得太快,并且请求无法完成。我不完全确定 JS 调用堆栈是如何工作的。

我的源代码如下:

var baseURL = 'http://www2.dailyfaceoff.com/teams/lines/';
var request = require('request'), 
    cheerio = require('cheerio'),
    urls = [],
    teams = [];


var teamPages = [13, 14, 15, 16, 17, 18, 19, 20, 21,
 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 
 35, 36, 37, 38, 39, 40, 41, 42]

 for(i in teamPages)
 {
    url = baseURL + teamPages[i];
    urls.push(url);
 }

 for(u in urls)
 {
    var team  = [];
    request(urls[u], function(err, resp, body)
      {
        if(!err && resp.statusCode == 200){
            var $ = cheerio.load(body);         
            var teamName = $('#newTitle').text();
            var players = [];
            $('#forwards td a img').each(function(){
                var name = $(this).attr("alt");
                players.push(name); });
            $('#defense td a img').each(function(){
                var name = $(this).attr("alt");
                players.push(name); });
            $('#goalie_list td a img').each(function(){
                var name = $(this).attr("alt");
                players.push(name); });
            //console.log(players);
            teams.push(players);    
        }
      });
 }
 console.log(teams);
 console.log('DONE');

【问题讨论】:

  • 您知道什么是异步响应以及它对您编写使用它们的代码意味着什么吗?如果没有,你需要做一些阅读,因为你目前的方法行不通。您可能还想阅读以下内容:stackoverflow.com/questions/14220321/…

标签: javascript parsing loops scope web-scraping


【解决方案1】:

有点奇怪,Node.js 是基于事件驱动的非阻塞模型。因此,在异步调用中使用像 for 这样的循环块时需要小心。尝试使用forEach 并给它一个函数处理程序。此外,仅当您确定所有请求都已满足时才打印结果。下面的代码可能会对您有所帮助,但它仍然不是 100% 正确/漂亮:

urls.forEach( function (url, index) {
  var team  = [];
  request(u, function(err, resp, body)
  {
     if(!err && resp.statusCode == 200){
        .
        .
        teams.push(players);

        // Print the teams when last response is done
        if ( index == urls.length - 1 )
          console.log(teams);
     }
  });
}

【讨论】:

  • 谢谢,这正是我认为的问题所在。我最初是在寻找一个使用 for each(url 中的 u)的异步模型,但我遇到了类似的问题。再次感谢您。
  • 习惯处理异步代码需要时间。继续学习!不客气,乐于助人! :)
猜你喜欢
  • 1970-01-01
  • 2018-05-23
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 1970-01-01
  • 2019-10-07
  • 2012-07-29
相关资源
最近更新 更多