2015-09-01 49 views
1

我现在知道how to load columns, of a table, from an external webpageUserscript循环几个HTTP请求并合并结果?

现在我想对扩大:

  • 从多个页面(由玩家持仓排名表)获取表格数据。
  • 将它合并到一个主表中。

This is the URL (http:...fantasysports.yahoo.com...pos=QB)该脚本当前提取。列是各个职位的团队名称和团队等级。

我想让它遍历其他位置(即WR,RB,TE)。这是通过将URL的最后2个字母更改为相应的值来完成的。然后我希望将所有这些数据放在一个数组中,其中第一列是团队名称,第二列是针对QB位置的排名#,第三列是针对WR位置的排名#,依此类推。

我的计划是将GM_xmlhttpRequest放在一个for循环中,该循环遍历不同的位置名称。
我的代码能够为职位显示单独的表格,但由于某些原因,他们没有按顺序排列。

我遇到的另一个问题是变量范围。目前newStatTableparseResponse函数中定义,但我无法从函数外部访问它。我试图从var newStatTable删除var,使其成为一个全球性的,但它没有奏效。

这里是我要寻找一个样本输出数组(注:我只是随机选择这些队伍):

TeamName    QB WR TE and so on... 
---      -- -- -- 
Jacksonville Jaguars 1 6 28 
Sanfrancisco 49ers  4 2 32 
Seattle Seahawks  31 5 10 

这里是我的尝试。

// ==UserScript== 
// @name  _Grab stuff of a *static*, third-party web site. 
// @include http://football.fantasysports.yahoo.com/* 
// @include https://football.fantasysports.yahoo.com/* 
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js 
// @grant  GM_xmlhttpRequest 
// ==/UserScript== 

pos = ["QB", "WR", "RB", "TE", "K", "DEF"]; 
for (x in pos) { 
    GM_xmlhttpRequest ({ 
     method:  "GET", 
     url:  "http://football.fantasysports.yahoo.com/f1/326198/pointsagainst?pos=" + pos[x], 
     onload:  parseResponse, 
     onerror: function (e) { console.error ('**** error ', e); }, 
     onabort: function (e) { console.error ('**** abort ', e); }, 
     ontimeout: function (e) { console.error ('**** timeout ', e); } 
    }); 
} 
function parseResponse (response) { 
    var parser = new DOMParser(); 
    var ajaxDoc   = parser.parseFromString (response.responseText, "text/html"); 
    var statRows  = ajaxDoc.querySelectorAll ("#statTable0 > tbody > tr"); 
    var newStatTable = $(statRows).map (function() { 
     var tblRow  = $(this); 
     var teamRank = parseInt (tblRow.find (".rank-indicator").text().trim(), 10); 
     var teamName = tblRow.find ("td:eq(1)").text().trim().split(" vs")[0]; 

     return [ [teamName, teamRank] ]; //Return Teamname, Rank # 
    }).get(); 

    console.log (newStatTable); 
} 
+0

所以你的问题是 - **他们不是为了**,对吗? - 我假设你知道httpRequests是异步的,那么你为什么期望它们是有序的呢? – Soren

+0

当我说“不按顺序”时,我的意思是WR数组显示在QB数组之前。在for循环中,它不是为了顺序吗? 此外,我更大的问题是,我试图找到一种方法来结合所有的表,就像在我的示例数组输出 – Bijan

+0

您的for循环顺序,但“GM_xmlhttpRequest”创建一个异步AJAX调用,并完成这些发生在for循环完成之后*,并且它们按您所调用的HTTP服务器决定完成它们的顺序完成 - 即以任意顺序完成。 – Soren

回答

1

AJAX,与the very definition异步。这意味着返回的数据将以任何顺序返回,除非您明确地将其复制出去,否则数据将不在回调函数外部提供。

因此,对于多页混搭,您必须有一定的方法来collat​​e必要的数据。 (在你的情况,你可以整理的队名。)

的一般做法是:

  1. 创建an Associative Array来保存数据。
  2. 在每个AJAX调用中传递一个上下文
  3. 使用该上下文来控制AJAX回调函数如何解析数据并将其整理到整个数组中。
  4. 监控AJAX调用的状态,并且只在全部完成时才进行最终处理。

下面是它看起来像一个userscript:

// ==UserScript== 
// @name  _Mash up tables from several *static*, third-party, web pages. 
// @match  *://football.fantasysports.yahoo.com/* 
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js 
// @grant  GM_xmlhttpRequest 
// ==/UserScript== 
const playerPositions = ["QB", "WR", "RB", "TE", "K", "DEF"]; 
const numPositions  = playerPositions.length; 
const baseURL   = "http://football.fantasysports.yahoo.com/f1/326198/pointsagainst?pos="; 
var rankingsTable  = {}; //-- This will be filled by the AJAX parser. 
var numPagesFetched  = 0; 

for (var J in playerPositions) { 
    GM_xmlhttpRequest ({ 
     method:  "GET", 
     url:  baseURL + playerPositions[J], 
     context: playerPositions[J], 
     onload:  parseResponse, 
     onerror: function (e) { console.error ('**** error ', e); }, 
     onabort: function (e) { console.error ('**** abort ', e); }, 
     ontimeout: function (e) { console.error ('**** timeout ', e); } 
    }); 
} 
function parseResponse (response) { 
    var playerPosition = response.context; 
    var parser   = new DOMParser(); 
    var ajaxDoc   = parser.parseFromString (response.responseText, "text/html"); 
    var statRows  = ajaxDoc.querySelectorAll ("#statTable0 > tbody > tr"); 
    var newStatTable = $(statRows).map (function() { 
     var tblRow   = $(this); 
     var teamRank  = parseInt (tblRow.find (".rank-indicator").text().trim(), 10); 
     var teamName  = tblRow.find ("td:eq(1)").text().trim().split(" vs")[0]; 

     return [ [teamName, teamRank] ]; 
    }).get(); 

    numPagesFetched++; 
    console.log ('Fetched page ' + numPagesFetched + ' of ' + numPositions + '.'); 

    /*--- Now loop over the fetched rows and collate them into the master table, depending 
      on playerPosition. 
    */ 
    var columnIdx  = playerPositions.indexOf (playerPosition); 

    for (var K in newStatTable) { 
     var teamName  = newStatTable[K][0]; 
     var teamRank  = newStatTable[K][1]; 
     var teamStats  = rankingsTable[teamName] || new Array (numPositions); 

     teamStats[columnIdx] = teamRank; 
     rankingsTable[teamName] = teamStats; 
    } 

    if (numPagesFetched === numPositions) { 
     displayFinalResult(); 
    } 
} 

function displayFinalResult() { 
    var sortedTeamNames = Object.keys (rankingsTable).sort (function (zA, zB) { 
     return zA.localeCompare (zB); 
    }); 

    const namePadStr = new Array (25).join (' '); 
    console.log (
     'Team      Ranks QB, WR, RB, TE, K, DEF\n' + 
     '------------------------ ------------------------------' 
    ); 
    for (var J in sortedTeamNames) { 
     var teamName = sortedTeamNames[J]; 
     if (rankingsTable.hasOwnProperty (teamName)) { 
      console.log (
       (teamName + namePadStr).slice (0, 24) + ' ', rankingsTable[teamName] 
      ); 
     } 
    } 
} 

我们会得到一大截的FF奖金的,对不对? ;)

+0

你一直对这个项目有很大的帮助。我有[最后一个问题](http://stackoverflow.com/questions/32360529)。并回答你的问题,如果我赢了,我会送你一个剪辑:) – Bijan