Script para monitorizar apuestas en MadBid

16

MadBid es una web de apuestas donde distintos usuario realizan pujas sobre productos cada cierto tiempo. Con el fin de obtener más información sobre el funcionamiento y evolución de estas subastas desarrollé el siguiente script.

Para más información sobre la historia de este desarrollo y otros detalles podéis consultar estos otros artículos:

En esencia, el funcionamiento del script es muy sencillo: básicamente se encarga de monitorizar el cambio de contenido de un div (a partir de su ID), que es donde aparece el nombre del jugador. Según va cambiando el contenido del div o nombre del jugador que puja (esto lo podéis ver yendo a una subasta de Madbid), el script va guardando un historial de estos cambios y generando un gráfico de los mismos.

Para ver el script en funcionamiento. lo primero que haremos es cargar una página con una de esas subastas de MadBid. Una vez cargada la página de la subasta que deseemos monitorizar, inyectamos el script en dicha página con el siguiente código:

javascript:var s = document.createElement('script');s.type='text/javascript';document.body.appendChild(s);s.src='http://polilabs.com/downloads/madbidmonitor.js';void(0);

Este código lo podemos ejecutar directamente copiándolo en la barra de direcciones de nuestro navegador,o creándonos un acceso a favoritos con dicho código.

Lo siguiente es identificar el ID del div en donde se van mostrando los nombres de los distintos jugadores. Esto lo podemos hacer fácilmente con las herramientas de desarrollo del navegador que utilicemos. En el caso de Chrome, la opción es «inspeccionar elemento».

Reconozco que esta es la parte menos usable del script para alguien que no esté habituado a utilizar estas herramientas, pero tiene su explicación. El ID del div cambia en cada carga de la página de subastas, y aunque sigue un patrón, hubiera añadido multitud de código innecesario para lo que andaba buscando. Además, si cambiaran ese patrón habría que reprogramar el script. De esta forma, en caso de que la página cambie se podrá seguir utilizando. O yendo más allá, así sirve para monitorizar otro tipo de cambios en cualquier otra web.

En un principio el script carecía de dependencias externas, pero a raíz de utilizar la librería de HighCharts para dibujar el gráfico es necesaria la presencia de jQuery. Afortunadamente la página de MadBid hace uso de esta librería, así que está obviada del código la comprobación y carga de esta librería.

Uno de los inconvenientes que tiene el script en su forma actual es el rendimiento. Cuando el script lleva funcionando algunos horas y la cantidad de datos a dibujar es muy alta, este tarda en actualizar el gráfico. Esto provoca que al final de las subastas, cuando el tiempo entre pujas es inferior a 5 segundos, no se puedan capturar todos los datos que aparecen.

Para paliar este problema es aconsejable realizar un zoom sobre el último tramo del gráfico. De esta forma la cantidad de datos a representar será menor y el gráfico se actualizará más rápidamente. Otras opciones podrían haber sido refrescar el gráfico bajo demanda, o abrir el script en otra ventana.

Un característica importante del script es que es completamente anónimo, por lo que, aunque lo inyectemos en la página de MadBid este no afectará en absoluto al correcto funcionamiento de la misma.

Y este es el script en cuestión:

/**
 * MadBid Apuestas Monitor v0.1
 * http://www.polimalo.com/ & http://polilabs.com
 * Copyright 2013, David Fernández
 * Licensed under the MIT or GPL Version 2 licenses.
 * Date: Apr 2 2013
 *
 * Copyright (C) 2013 by David Fernández
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
(function(){
	var madbidMonitor = {};
	madbidMonitor = function() {
		this.layerMonitor = null;
		this.players = Array();
		this.totalPujas = 0;
		this.lastPlayerName = "";
		this.oContent = null;
		this.timer=0;
		this._init();
		this.chart = null;
		return this;
	};
	madbidMonitor.prototype = {
		_init:function() {
			var _this = this;
			var w = window,
			    d = document,
			    e = d.documentElement,
			    g = d.getElementsByTagName('body')[0],
			    x = w.innerWidth || e.clientWidth || g.clientWidth,
			    y = w.innerHeight|| e.clientHeight|| g.clientHeight;
			var layer = document.createElement("div"); 
			layer.style.position = 'absolute';
			layer.style.top = "0px";
			layer.style.right = "0px";
			layer.style.background = "#555";
			layer.style.border = "1px solid #fff";
			layer.style.color = "#fff";
			layer.style.width = "140px";
			layer.style.height = y+"px";
			layer.style.overflow ='scroll';
			layer.style.fontSize = '10px';
			document.body.appendChild(layer);
			this.oContent = layer;
			//
			var o = document.createElement("div");
			o.id = 'madbidmonchart';
			o.style.position = 'fixed';
			o.style.bottom = "20px";
			o.style.left = "0px";
			o.style.background = "#555";
			o.style.border = "1px solid #333";
			o.style.color = "#fff";
			o.style.width = (x-160)+"px";
			o.style.height = (y-300)+"px";
			document.body.appendChild(o);
			//
			var idDivText = this._getRandomID();
			var idDivBtn = this._getRandomID();
			layer.innerHTML += '<input type="text" id="'+idDivText+'"/>';
			layer.innerHTML += '<input id="'+idDivBtn+'" type="button" value="GO MONITOR"/>';
			//
			var script = document.createElement('script');
			script.onload = function(){_this.Charts()};
			script.src = "http://code.highcharts.com/highcharts.js";
			document.getElementsByTagName('head')[0].appendChild(script);
			//
			document.getElementById(idDivBtn).addEventListener('click', function(){
				_this.layerMonitor = document.getElementById(document.getElementById(idDivText).value);
				setInterval(function(){_this.IntervalMonitor.call(_this)},100);
			});

		}
		,
		_getRandomID : function(){
			return Math.floor((Math.random()*100000000)+1);
		}
		,
		findPlayer : function(name) {
        	for(var n=0; n<this.players.length; n++) {
        		if(this.players[n].name==name) return n;
        	}
        	return false;
        }
		,
		IntervalMonitor : function() {
			this.timer += 0.1;
			if(!this.layerMonitor) return;
			this.oContent.style.top = window.pageYOffset+"px";

			if(this.layerMonitor.style.display=='none'){
				this.lastPlayerName='';
				return;
			}

			var actualPlayerName = this.layerMonitor.innerText;
			var actualPlayer = this.findPlayer(actualPlayerName);
			if(actualPlayer===false) {
				this.players.push({name:actualPlayerName, pujas:1, history: [this.timer]});
				this.chart.addSeries({name:actualPlayerName, data:[[this.timer,1]]});
				this.lastPlayerName=actualPlayerName;
				this.totalPujas++;
			}
			else {
				if(this.lastPlayerName!=actualPlayerName){
					this.players[actualPlayer].pujas++;
					this.players[actualPlayer].history.push(this.timer);
					this.chart.series[actualPlayer].addPoint([this.timer, this.players[actualPlayer].pujas]);
					this.lastPlayerName=actualPlayerName;
					this.totalPujas++;
				}
			}

			this.Paint();
		}
		,
		Paint : function() {
			this.oContent.innerHTML = "<b>Total pujas:</b> " + this.totalPujas+"<br>";
			for(var n=0; n<this.players.length; n++){
				this.oContent.innerHTML += "<b>"+this.players[n].name+":</b> "+this.players[n].pujas+"<br>";
			}
		}
		,
		Charts : function() {
			this.chart = new Highcharts.Chart({
            chart: {
            	renderTo: 'madbidmonchart',
                type: 'line',
                animation: false,
                zoomType: 'x'
            },
            title: {
                text: 'MADBID APUESTAS MONITOR'
            },
            subtitle: {
                text: 'by <a href="http://www.polimalo.com/" target="_blank">PoliMalo.com</a> / <a href="http://polilabs.com/" target="_blank">PoliLabs.com</a>'
            },
            xAxis: {
                type: 'linear'
            },
            yAxis: {
                title: {
                    text: 'Apuestas'
                },
                min: 0
            },
            tooltip: {
                formatter: function() {
                        return '<b>'+ this.series.name +'</b><br/>'+ (this.x/60.0).toFixed(2) +' min<br> '+ this.y+" apuestas";
                }
            },
            plotOptions: {
	            series: {
	                marker: {
	                    radius: 2
	                },
	                lineWidth: 1
	            }
	        },
            series: []
        });
		}
	}

	new madbidMonitor();

})();

 

One Comment

  • Carlos
    26 junio, 2013 a las 19:07

    Hola, muchas gracias por el script, estoy aprendiendo javascript con él. Pero creo que el problema de que no cuente muchas pujas no es por actualizar el gráfico, porque borre el gráfico y solo me quedé con la «caja» que cuenta las pujas y el valor tampoco coincidía. Se cuentan muy fácil al ser una puja un céntimo.
    El fallo creo que es de madbid que no actuliza lo suficiente rápido los pujadores y entonces si dos pujadores pujan muy juntos la página de madbid no es actualizada a tiempo y se salta pujadores. Este efecto se puede notar mejor si entramos dentro de un producto que nos muestra los últimos pujadores se puede apreciar que se saltan a pujadores.
    Un saludo.