Promoting team rivalry through Fantasy Football

Robin have you played your wildcard yet!?

As soon as I joined NET-A-PORTER I was absorbed into the company Fantasy Football League by equal parts peer pressure and wanting to look cool. The first season took its toll. Forget lying in on a Saturday — I needed to triple-check my captain selection, I wouldn’t dare to take a holiday in case a player got injured while I was away, never mind the fear of forgetting about double-game weeks. After a respectable lower-middle-half-table finish, I needed a break — a long break.

The NAP Tech team consists of multiple sub-teams, so naturally there is some friendly competition; when a company-wide league was announced, I knew I had come out of retirement.

We have two main leagues: one strictly for NAP Tech; and NET-A-LIGA (a.k.a. big boy school), the company-wide league for people who know what they are doing.

If we were going to make this a real success, we had to amplify the rivalry and the potential for gloating — that is what this post is about.

The Fantasy Football service


I wanted to be able to view any Fantasy Premier League table as pure data so I could make a bespoke display for the NAP Tech league. The website didn’t appear to do this, so I thought I would create my own.


Using Node, I created a simple REST service that returns any league in JSON. Below is a breakout of some of the modules used:


Restify is more or less a trimmed-down version of Express, allowing for rapid development of REST services. If you want to get started quickly, there is a Yo generator, restify-live. However, our app used our own bootstrap as we didn’t want to use CoffeeScript.


Initially, I thought I would need to get the application to log into my account before using a request to collect the mark-up. However, all leagues seem to be public:

$ curl

So no need to log in, just build a URL with the relevant league code.


Once I had the page source, I wanted to do some DOM manipulation. As with any scraping tool, I’m completely dependent on the web site not changing the mark-up. So I used cheerio to convert the HTML into an array of objects:

function buildLeagueObj (html) {
    $ = cheerio.load(html);
    var tableRows = $('.ismStandingsTable tr').length + 1;
  var arr = [];
    for (i = 3; i <= tableRows; i++) { 
        var element = '.ismStandingsTable tr:nth-child(' + i +')'
    var obj = {
      positionMovement: checkPositionMovement($(element + ' td:nth-child(1) img').attr('src')),
      position: $(element + ' td:nth-child(2)').text(),
      team: $(element + ' td:nth-child(3)').text(),
      manager: $(element + ' td:nth-child(4)').text(),
      gameWeek: $(element + ' td:nth-child(5)').text(),
      total: $(element + ' td:nth-child(6)').text(),
  return arr

function checkPositionMovement (imageURL) {
    switch (imageURL) {
    case "":
        return "-"
    case "":
        return "up"
    case "":
        return "down"
        return "-"


I deployed the app on Heroku, presuming that a free account would be fine to handle the internal traffic. I always think a sign of a good service is that I can make it work, first time, after skimming the “Getting started” documentation. Judging it by that standard, Heroku is great; the application was running after the first commit, in about five minutes.

You can see a preview of the top scoring fantasy league here:

Monitoring our position


Finally, I wanted a quick way to show the league on a big screen. I thought about creating an Express server to build a bespoke look and feel, but I was not sure if I could convince my Head of Technology to agree to removing site monitoring for our team table… So, I thought: “why not include it with our monitoring?

I played around with Geckoboard as a way of displaying our metrics (and our league table), and here are my thoughts on what I liked and what I didn’t:

What I liked

  • quick to get up and running
  • out of the box it has integration with lots of services: AWS, Google Analytics, Jenkins, JIRA and plenty more
  • nice modular widget and gridding system
  • free trial

What I didn’t like

  • when building a custom widget, I’d hoped I could map my API to their data visualisation cue points, but each widget requires a specific endpoint response
  • Geckoboard does not store any data; if you want to plot multiple points over time to a custom graph, you need to send every individual piece of data
  • although there is a lot of freedom with the grid, you are still limited to the fixed sizes that are available for widgets
  • the entry price of $17 per month seems high to me

To add the table to our board, I created a custom HTML text widget using a bespoke endpoint (here showing the current most-successful league):

This adds a bunch of CSS to tidy up the look of the table:

function buildGeckoResponse (html) {
  $ = cheerio.load(html);
  var response = {item: [
    {text: '.fantasy-league td {padding:5px}<table class="fantasy-league" style="font-size: 15px;width: 100%">' + $('table.ismStandingsTable').html() + '</table>'}
  return response;


I suppose different team members’ feelings towards this project could correlate with their current league position on a Monday morning. There is no better example of this than last Monday; my manager could not look happier pointing to the top of the table, while I felt regret about taking out my supposedly injured captain who then went on to score a hat-trick.

Even though this idea was just a bit of fun, it serves to highlight that modern technology and services are allowing us to be more creative, and to deliver results faster and more cheaply. If you want to prototype an idea, you can now mock up a service, create a web application, configure a build process, deploy the app and scale the infrastructure all by yourself within a few hours.

Please contribute!

If you are interested in the Fantasy Football Service, it’s on Github and is open for contributions.

Print Friendly

Leave a Reply