2015-09-01 44 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