Userscript循环遍历多个HTTP请求并合并结果? [英] Userscript to Loop over several HTTP Requests and combine the results?

查看:147
本文介绍了Userscript循环遍历多个HTTP请求并合并结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在知道如何加载列,来自外部网页的表格。

I now know how to load columns, of a table, from an external webpage.

现在我想扩展它并且:


  • 从多个页面获取表格数据(按玩家位置排名)。

  • 将其合并到一个主表中。

这是脚本当前提取的URL(http:... fantasysports.yahoo.com ... pos = QB)。列是团队名称和团队在各个职位的排名。

This is the URL (http:...fantasysports.yahoo.com...pos=QB) that the script currently fetches. The columns are the team name and the team's rank for the various positions.

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

I want to have it iterate over other positions (i.e. WR, RB, TE). This is done by just changing the last 2 letters of the URL to its respective value. I then want to have all this data in a single array where first column is the team name, second column is the ranking # for the QB position, third column is ranking # for WR position, and so on.

我的计划是将 GM_xmlhttpRequest 放在循环中,迭代不同的位置名称。

我的代码能够显示位置的单独表格,但由于某种原因它们不合适。

My plan was to put the GM_xmlhttpRequest in a for loop that iterates over the different position names.
My code is able to display separate tables for the positions but for some reason they are not in order.

另一个问题我碰到变量范围。目前 newStatTable parseResponse 函数内定义,但我无法从函数外部访问它。我尝试从 var newStatTable 中删除​​ var ,使其成为全局但不起作用。

Another issue I ran into was the variable scope. Currently newStatTable is defined inside the parseResponse function but I am unable to access it from outside the function. I tried removing var from var newStatTable to make it a global but it did not work.

这是我正在寻找的示例输出数组(注意:我只是随机选择了这些排名):

Here is a sample output array that I am looking for (Note: I just randomly selected these ranks):

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);
}


推荐答案

AJAX,是异步的< a href =https://en.wikipedia.org/wiki/Ajax_%28programming%29 =nofollow>定义。这意味着返回的数据将以几乎任何顺序返回,并且除非您明确地将其复制出来,否则数据将不会在回调函数之外可用。

AJAX, is asynchronous by the very definition. This means that the returned data will come back in just about any order, and the data will not be available outside the callback function(s) unless you explicitly copy it out.

因此,对于多页mashup,您必须有一些方法整理数据。 (在您的情况下,您可以整理团队名称。)

So, for multi-page mashups, you must have some way to collate the data as necessary. (In your case you can collate on team name.)

一般方法是:


  1. 创建用于保存数据的关联数组

  2. 在每次AJAX调用中传递上下文

  3. 使用该上下文来控制AJAX回调函数如何解析数据并将其整理到整个数组中。

  4. 监视AJAX调用的状态并且只有在完成后才进行最终处理。

  1. Create an Associative Array to hold the data.
  2. Pass a context in each AJAX call.
  3. Use that context to control how the AJAX callback function parses the data and collates it into the overall array.
  4. Monitor the status of the AJAX calls and only do final processing when they are all complete.

以下是用户脚本中的内容:

Here's what it looks like in a 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奖金很大,对吧? ;)

We're going to get a large cut of your FF winnings, right? ;)

这篇关于Userscript循环遍历多个HTTP请求并合并结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆