Recogiendo datos para estadísticas en nuestro WEB
Una metodología para saber quién nos visita

Fecha: 17/Feb/2005 (11/02/05)
Jose Alfredo García Guirado http://jgarcia.g-softsolutions.de/Contacto.aspx
 

 


Introducción

En este artículo se explica una metodología de obtener los datos necesarios para saber la procedencia de nuestros visitantes en un sitio Web y como almacenarlos para su posterior tratamiento estadístico. La metodología viene acompañada de un ejemplo concreto de uso.

SECCION I- La información de nuestros visitantes una mina de oro para saber como funciona nuestro sitio Web.

SECCION II- Planificando la toma de datos.

SECCION III- La Lógica de adquisición de datos.

SECCION IV- Implementando la solución.

Conclusiones

SECCION I : La información de nuestros visitantes una mina de oro para saber como funciona nuestro sitio web.

La colección de información de nuestros visitantes es un aspecto a veces descuidado del diseño de nuestro sitio WEB, muchas veces nuestro proveedor nos suministra una serie de estadísticas que a menudo son suficientes para el trabajo normal pero a veces le falta la información que realmente necesitamos, o la posee pero hay que pagarla con un costo extra.

Los usos de la información son imnumerables, acá solo haremos énfasis en dos usos: el técnico y el comercial.

La posesión de la información, sobre toda la técnica nos habilita para saber si de verdad nuestro web se esta viendo bien o todos esos preciosos efectos en frames o javascript son en vano porque un por ciento alto de nuestros visitantes lo tienen deshabilitado. También sabremos si el visitante posee el net framework instalado, habilitandonos para bajar un control que lo requiera o ActiveX.

Por la parte comercial, si tenemos anuncios en sitios WEB podemos saber si estos son realmente productivos, si conocemos de donde vino nuestro visitante, otros aspectos importantes es, que hizo el visitante en nuestra web y el tiempo que estuvo en ella.

SECCION II : Planificando la toma de datos

Un proceso de toma de datos para estadísticas de nuestros visitantes topa con los siguientes problemas de diseño:

La solución técnica a estos problemas es sencilla, podemos ver en la siguiente figura una descripción gráfica del modelo propuesto:

Esquema general de diseño

La mejor solución, desde el punto de vista de cumplir nuestros criterios de diseño es, incluir el código de toma de estadísticas en una página base de la cual hereden todas las páginas de nuestro sitio Web. Esto es muy simple de hacer, de hecho solo hay que crear dicha página base (como una clase descendiente de Page)

Los datos se almacenaran en un fichero, del cual posteriormente se puede hacer un analisis estadístico. El contenido de este fichero puede ser analizado on-line o bajado a tierra mediante FTP o mediante un servicio WEB.

Para posibilitar la facil adaptación de las estadísticas a diferentes sitios Web se organizará el código de la misma en un proyecto independiente de modo que el resultado sea un ensamblado propio que se agrega al directorio /bin del sitio Web en que se quiera aplicar.

SECCION III : La lógica de Adquisición de datos

Existen dos puntos importantes a diferenciar a la hora de recoger información del usuario: el arribo del usuario a nuestro WEB y el camino que hace el usuario dentro del mismo. No es necesario recoger una y otra vez los datos del mismo usuario, en nuestro fichero de datos. Es por eso que se hace necesario implementar una solución que pueda identificar cuando el usuario arriba a nuestra página y cuando está ya registrado haciendo un recorrido interno.

En esta solución se usa una variable de Session que toma valores al entrar el usuario en el WEB y luego mediante su consulta se puede determinar si está haciendo un recorrido interno.

A continuación se muestra el diagrama de bloques general del algoritmo empleado:

Lógica de toma de datos

Si ya está identificada la persona, el algoritmo solo recoge la URL actual del Request y la fecha y hora en que el visitante hace el presente Request.

A continuación veremos paso por paso como es implementada la solución.

SECCION IV : Implementando la solución

Ahora veremos paso por paso, como insertar en nuestro sitio Web la recogida de información.

1.- Creando una página base única para todas las páginas aspx del WEB

Simplemente cree un fichero de clase con el nombre PageBase (ú otro que usted desee), y agrégele como Objeto del cual hereda, el objeto Page. (necesitará agregar el namespace System.Web.UI)En la siguiente figura se puede observar , en rojo donde agregar la clase madre.

public class PageBase :Page
{
//Codigo de recogida de información de usuario.........
}

Dicha página base es heredada por todas las páginas aspx de nuestro WEB. Para que dicha página sea la base de nuestras páginas ya desarrolladas, cambie en cada pagina aspx el objeto del cual hereda la clase a la clase PageBase. En el ejemplo debajo se aprecia donde colocar el objeto en rojo

namespace jagg.jgarcia
{
/// <summary>
/// Summary description for Impressum.
/// </summary>
public class Impressum : PageBase
{
}

Usar una página base es práctica común en el desarrollo WEB ya que es muy útil para centralizar operaciones que ocurren en todos las páginas, como por ejemplo elegir un idioma entre varios posibles, en los WEB multiidiomas.

2.- Creando un lugar para guardar nuestros datos.

Necesitaremos un lugar para guardar el fichero con los datos de nuestros usuarios, se recomienda crear un directorio propio para esto (en nuestro ejemplo lo llamamos /log). Es necesario para poder impedir que los usuarios normales del WEB accedan a el. Este directorio tiene que tener algunos consideraciones especiales:

En dicho lugar tambien crearemos un pequeño fichero XML para controlar el número consecutivo que le daremos a cada visitante. El mismo se muestra a continuación.

<?xml version="1.0"?>
<ConfigData xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<VisitanteNum>1</VisitanteNum>
</ConfigData>
 

No necesitaremos crear ningún fichero para las estadísticas porque se encargará el mismo código de hacerlo.

3.- Creeemos un proyecto para nuestras clases de estadísticas.

Eel proyecto será un simple proyecto de clases en c#, ya que no necesitaremos interfaz de usuario. El proyecto se compondrá de dos archivos de clases. Para nuestro ejemplo lo hemos llamado:Configuration.cs y WebStadistica.cs respectivamente

3.1.- El Archivo Configuration.cs

En este archivo sencillamente pondremos las variables necesarias para poder adaptar el ejemplo a nuestras necesidades. En ella declaramos el nombre y el camino de nuestros dos ficheros auxiliares. Si usted desea usar otro nombre y otro camino aquí puede realizar los cambios.

using System;

namespace jagg.services
{
    /// <summary>
    /// Summary description for Configuration.
    /// </summary>
    public class Configuration
    {
        //Fichero de recogida de estadisticas
        public static string logfile    =    @"log\estadisticas.txt";
        //Fichero de configuracion
        public static string configfile =    @"log\config.xml";
    }
}
 

3.2.- El archivo WebStadistica.cs

Es propiamente acá donde desarrollamos el meollo de la aplicación. La clase más importante a usar es HttpRequest del System.Web. Utilizaremos además las clases de IO y XML para manejar el acceso a los ficheros. El el diagrama inmediato abajo se observan las clases usadas de NET y el constructor de la clase WebStat. Observe que solamente se inicializan los variables con los nombres y caminos de los ficheros de config.xml y estadisticas.txt

using System;
using System.Web;
using System.IO;
using System.Xml.Serialization;
using System.Xml;

namespace jagg.services
{
    /// <summary>
    /// Clase WebStat contenedora de la recoleccion de datos.
    /// </summary>
    public class WebStat
    {
        string LogFile;
        string LogLine;
        public WebStat()
        {
            LogFile = HttpContext.Current.Request.PhysicalApplicationPath 
             + Configuration.logfile;
            LogLine = "";
        }
 

A continuación listamos la rutina de recogida de datos en sí. Este es el centro de la aplicación. Observe que la variable de Session IDVisita determina que sección del programa se ejecutará. A esta variable se accede mediante una propiedad de forma tal que si posee un valor null devuelve -1, así podremos conocer cuando el usuario acaba de ingresar a el WEb, en ese caso se ejecuta la sección else del programa y dicha variable es inicializada con un número de visitante tomado del contenido del fichero Config.xml.

El resto de la rutina consiste en acceder a las clases HttpContext.Current.Request para tomar la información de recorrido de nuestro visitante y la información técnica de la clase HttpBrowserCapabilities. Observe que la información es almacenada en un fichero de formato texto, separado por comas, usamos este formato por ser más compacto que el XML debido que en la aplicación real que utiliza este ejemplo, el fichero de datos es bajado vía un Web Servicio para su procesamiento.

public bool  GetStadisticas(System.Web.HttpRequest rq)
        {
            if (VariablesSession.IDVisita != -1 ) 
            {
                //El usuario ya existe recoger solo los datos de visitas de página
                LogLine = Convert.ToString(VariablesSession.IDVisita,10)+ ",";
                LogLine +=  DateTime.Now    + ","    ;    // Fecha
                LogLine +=  ","                        ;    // de donde viene no es necesario
                LogLine += rq.Url            + ","   ;    // URL destino
                LogLine += ",,,,,,,,";                   //Compatibilidad
            }
            else
            {
                //El usuario no existe crear como nuevo
                //Recoger numero de visitante en fichero
                string fich = HttpContext.Current.Request.PhysicalApplicationPath + Configuration.configfile;
                XmlSerializer ser = new XmlSerializer(typeof(ConfigData));
                //Leyendo con un reader
                XmlTextReader rdr = new XmlTextReader(fich);
                ConfigData cd;
                cd = ser.Deserialize(rdr) as ConfigData;
                rdr.Close();
                //Guardando el id de visitante en una variable de sesion
                VariablesSession.IDVisita = cd.VisitanteNum;
                LogLine = Convert.ToString(cd.VisitanteNum,10)+ ","    ;
                //Incrementando el valor del fichero de visitantes
                cd.VisitanteNum++;
                //Guardando el valor incrementado
                XmlTextWriter xtw = new XmlTextWriter(fich,null);
                ser.Serialize(xtw,cd);
                xtw.Flush();xtw.Close();
                //Guardando otro datos de estadisticas.......
                HttpBrowserCapabilities bc = rq.Browser;
                LogLine += DateTime.Now       + ","    ;    // Fecha
                LogLine += rq.UrlReferrer     + ","    ;    //Recogida de la dirección de procedencia
                LogLine += rq.Url + ","                ;    //Recogida del punto de entrada
                LogLine += rq.UserHostName    + ","    ;    //Hostname de procedencia (o IP adress)
                LogLine += bc.Browser          + ","    ;    //Recogida del Explorador de Windows usado
                LogLine += Convert.ToString(bc.MajorVersion,10) + ",";//Versión del browser
                LogLine += Convert.ToString(bc.MinorVersion) + ",";//Versión del browser
                LogLine += bc.Platform          + ","    ;    //Sistema operativo del cliente
                LogLine += bc.Frames          + ","    ;    //Si soporta frame el browser
                LogLine += bc.JavaScript      + ","    ;    //Si soporta javascript
                LogLine += bc.ActiveXControls + ","    ;    //Sis soporta ActiveX
                LogLine += bc.ClrVersion;                //Que versiones de NET tienen instalado
            }
            //LogLine += rq.UserAgent; 
            //Depositar los datos en el fichero de log pasado como parametro
            if (File.Exists(LogFile) == false)
            {//Crear el file
                StreamWriter temp= File.CreateText(LogFile);
                temp.Close();
            }
            StreamWriter sw = File.AppendText(LogFile);
            try
            {
                sw.WriteLine(LogLine);
                return true;
            }
            catch
            {
                return false;
            }
            finally
            {
                sw.Flush();
                sw.Close();
            }
        }

 

El resto del archivo consta de los procedimientos auxiliares y se lista a continuación. Lo más revelante en estas clases es el modo de tratar la variable de Session para evitar que de una excepción cuando se encuentre vacia.

public class ConfigData
    {
        public int VisitanteNum = 0;
    }

    public class VariablesSession
    {
        static public int IDVisita
        { 
            set {HttpContext.Current.Session["Visita"] = (int) value;}
            get 
            {
                if (HttpContext.Current.Session["Visita"] == null)
                {return -1;}
                else
                {
                    return (int)HttpContext.Current.Session["Visita"];
                }
            }
        }
    }
 

4.- Utilizando WebStat en nuestra WEB

Para utilizar el programa, compilamos el proyecto y luego, si estamos en Visual Studio, solo es necesario agregar una referencia a nuestro proyecto en el proyecto del sitio Web que queremos agregar la recogida de datos estadísticos. Si no disponemos de Visual Studio, entonces abría que copiar manualmente el archivo dll resultante del proyecto a el archivo bin del Web Site.

Luego vamos a la página base creada, agregamos el namespace escogido (en nuestro ejemplo jagg.services) y agregamos un evento Page_Load con el siguiente código:

private void Page_Load(object sender, System.EventArgs e)
{
            //Obteniendo estadisticas del visitante
            WebStat ws = new WebStat();
            ws.GetStadisticas(this.Request);
}

eso es todo, compile el proyecto y navege por su web, luego puede observar en el archivo de estadisticas.txt los valores almacenados.

5.- Posibles errores

Si obtiene al ejecutar el programa errores del tipo de no tener suficiente nivel de acceso o acceso denegado, remitase al punto 2 de esta sección y revise si concedió al usuario NET los permisos necesarios para escribir y modificar el directorio /log.

Conclusiones

Hemos explorado en este artículo una manera simple de obtener los datos de nuestros visitantes para su posterior procesamiento estadístico. En el programa se a hecho énfasis en el hecho de poder minimizar la cantidad de código en las páginas del web, concentrándolo en un solo punto. Además se mantuvo el código dentro de un ensamblado aparte para poder tener la máxima portabilidad del mismo.

Por supuesto que estos no son la totalidad de los datos a obtener, se pudiera también recoger mediante JavaScript la resolución de la pantalla del visitante o los datos de preferencia de lenguajes. Revise la clase HttpBrowserCapabilities para una lista de todas las opciones disponibles.

Tenga en cuenta que se ha trabajado poco en esta rutina (por motivos de claridad) la protección contra errores, es aconsejable, si va a usarla en un ambiente de producción, trabajar más la respuesta ante excepciones.



Espacios de nombres usados en el código de este artículo:

System
System.Web
System.Xml
System.IO

 


ir al índice