sábado, 5 de agosto de 2017

Extraer Datos Estructurados, desde Sitios Web con Scrapy.


Vamos a explicar como utilizar  Scrapy, el cual es un framework open source construido con python, permite recuperar información desde paginas webs en forma estructurada.

Como ejemplo, utilizaremos el sitio web de supercom.gob.ec, en dicho sitio existe una pagina con un listado de medios de comunicación del Ecuador con la siguiente información: Nombre, sitio web, redes sociales. Vamos a trabajar con los canales de televisión. 

Para trabajar con Scrapy, demos tener conocimientos básicos sobre:
  • Ejecutar script con Python.
  • Conocer Html/CSS, o XPath.

Utilizaremos  Selectores CSS, para obtener un listado de medios de televisión existentes en Ecuador, los cuales se encuentran en la siguiente pagina:


Lo primero que debemos hacer, es analizar donde se encuentran los datos que vamos a extraer, para lo cual buscamos selectores CSS o etiquetas HTML que contengan los datos, podemos utilizar la herramienta de desarrollo del Chrome para este fin.



Figura 1. Inspector de Elementos de las herramientas de Desarrollo de Chrome.

El inspector de elementos, nos indica que la información de cada canal de televisión se encuentra dentro un "div" el cual posee una clase css "span6", dicho div contiene toda la información del canal de televisión, observe la figura 1. 

<div class="span6">
... Información del Canal ...
 </div>
Dentro de este bloque, el nombre del canal se encuentran en una  etiqueta "h2", con css "lead page-header", adicional el nombre es un enlace web, por lo tanto esta encerrado en una etiqueta  "a". Con el cual podemos utilizar el selector 'h2.page-header a' para obtener el nombre del canal. 

<h2 class="lead page-header">
<a href="...">TV Satelital</a> 
</h2>

Con los selectores analizados,  vamos a crear el spider de scrapy. Para lo cual creamos un archivo television_spider.py con el siguiente código:



Explicamos linea por linea:
  • Linea 1. Importar la librearía scrapy.
  • Linea 3. Creamos nuestro spider, para lo cual hacemos una clase "TelevisionSpider" que herede de la clase "scrapy.Spider".
  • Linea 4. Le damos un nombre a  nuestro spider, utilizando la propiedad 'name'.
  • Linea 5. Establecemos las urls de las paginas web de las cuales vamos a obtener los datos. Para lo cual utilizamos la propiedad start_urls
  • Linea 7. Sobrecargamos el  método parse  de la clase, este método posee un parámetro response, el cual nos permite procesar el contenido de las urls establecidas en la Linea 5. 
  • Linea 9. Conocemos que cada canal de televisión, esta dentro de un <div class='span6>...</div>, entonces utilizamos el selector css 'div.span6'. El objeto response contiene un método css, el cual permite utilizar selectores css para extraer información. La instrucción "for tv in response.css('div.span6'):", indica al spider que obtengan todos los elementos que cumplan el selector, recorremos cada elemento encontrado.   
  • Linea 10,11,12. Para obtener el nombre del canal de televisión utilizamos el selector css 'h2.page-header a', como nos interesa el texto de la etiqueta "a", utilizamos la variante "::text", por lo cual el selector final seria 'h2.page-header a::text'. Utilizamos el método extract_first(), para guardar el contenido en el campo 'titulo' de nuestros datos extraídos.  

Para ejecutar nuestro spider utilizaremos el siguiente comando:

>>scrapy runspider television_spider.py -o datos.json

Nota. Observe que el nombre del  archivo "television_spider.py", debe corresponder al nombre de la clase del spider, en este caso sera  "TelevisionSpider" con estilo PascalCase.

Los datos generados son los siguientes:

Como se observa al final existen dos elementos nulos, esto se debe a que el selector "div.span6" se utiliza en otra parte de la pagina para algo diferente que contener la información del canal. Debemos ser mas específicos en el selector, podemos utilizar el contenedor de todos los canales, en este caso es "div.entry-container", por lo cual nuestro selector seria "div.entry-container div.span6".


Volvemos a ejecutar el spider con los cambios realizados, esta vez los datos generados no existen elementos nulos.

Hasta el momento se ha obtenido el nombre del canal, para obtener los otros datos,  analizamos las etiquetadas html y clases css, que contenga dichos datos. A continuacion se enumeran los diferentes datos con los selectores correspondientes que los contienen:
  • Dirección: div.spField.field_direccion
  • Teléfono: div.spField.field_telefono
  • Fax:  div.spField.field_fax
  • Sitio Web: div.spField.field_sitio_web
  • Email: div.spField.field_email
  • Twitter: div.spField.field_twitter

Con este análisis, modificamos nuestro código para recuperar todos los datos:

El listado completo de canales, se encuentra en varias paginas, en nuestro ejemplo exactamente en cinco paginas. Podemos utilizar una opción estática para obtener toda la información, la cual consiste en  colocar el listado de todas las cinco url de las paginas en la propiedad "start_urls" de  la clase.

Esta opción estática, no es muy recomendada, scrapy posee opciones mas dinámicas que nos permiten tratar escenarios de paginación, en un próximo post explicaremos estas opciones.








lunes, 25 de julio de 2016

Hacer un Juego con HTML5 / Canvas. Parte 3.

Realizado los dibujos del juego (Hacer un Juego con HTML5 / Canvas. Parte 1.), y el código para rotar el cuadrado con los triángulos de colores al hacer click (Hacer un Juego con HTML5 / Canvas. Parte 2.), vamos aumentar el código con el mecanismo de circulo que cae desde la parte superior y que debemos hacer coincidir en el color con el triangulo superior.

Vamos a cambiar el código para dibujar los triángulos dentro del cuadrado,  iniciando con el triangulo superior, luego continuamos a la derecha, luego el triangulo inferior, y por ultimo el triangulo de la izquierda, es decir siguiendo el orden de las manecillas del reloj, el mismo orden que sigue al momento de rotar el cuadrado con el click.

Tenemos una matriz de cuatro colores [Color1,Color2,Color3,Color4], el Color1 se utiliza para el triangulo superior, el Color2 para el triangulo derecho, y así sucesivamente. Para conocer que color se encuentra actualmente en la parte superior vamos a utilizar el valor de rotación actual: Según este valor tenemos 0 => Color1, 90 => Color2, 180=> Color3, 270 => Color4.

Por lo tanto la formula para obtener el numero de color es; Rotación Actual / 90.

Para realizar el mecanismo de caída del circulo, colocamos una variable de velocidad a Ball, dicho valor aumenta el valor de "y" de Ball en cada ciclo de animación, con lo cual le damos el movimiento al circulo.

En cada ciclo de animación, debemos verificar si el circulo se encuentra colisionado con el cuadrado, si es el caso debemos verificar si el color de Ball coincide con el valor del triangulo superior para reiniciar el valor de "y" de Ball a 0, para que comience a caer desde la parte superior nuevamente con otro color "aleatorio" de los cuatro colores posibles. Si no coincide el color finalizar el juego.

Para reiniciar nuevo juego, si perdemos, damos un click.

Debemos colocar algún contador de cantidad de aciertos que se ha tenido, para lo cual vamos a crear un objeto "Scope" para realizar esto.

El código y resultado a continuación:


See the Pen Juego - Canvas. Parte 3 by Juan Carlos Saavedra (@jcsuscriptor) on CodePen.

domingo, 24 de julio de 2016

Hacer un Juego con HTML5 / Canvas. Parte 2.

Un vez que hemos dibujado los elementos del juego en la parte 1, vamos a proceder a colocar el código para permitir rotar el cuadrado al dar un click.

Los ángulos de rotación serán 0, 90, 180, 270, 360, para lo cual vamos a tener una variable global para almacenar el valor actual de rotación, en cada click se aumentara en 90 este valor, si llega a 360 el valor sera establecido a 0, de esta forma tenemos un ciclo continuo.

Todo el contenido de canvas, es una imagen, por lo que si deseamos tener interacción debemos volver a dibujar el contenido del mismo. Para esto vamos a utilizar un animación continua utilizando window.requestAnimationFrame, que nos permite llamar a una función en cada ciclo de animación.

 function play(){
    //1. Limpiar todo el contenido del canvas
    ctx.clearRect(0, 0, canvas.width, canvas.height);  
   
    //2. Dibujar el contenido
    ...
    ctx.rotate((Math.PI / 180) * rotate); 
    square.draw(); 
   
    //3. Continuar con el siguiente ciclo de animacion
    window.requestAnimationFrame(play); 
 }
 
 window.requestAnimationFrame(play);


Antes de dibujar el cuadrado con los triangulos realizamos una rotacion, segun el valor global de la variable rotate. Utilizamos "Math.PI/180 * Grados" para convertir los grados a radianes que utiliza ctx.rotate(radianes)

Vemos el resultado:

See the Pen Juego - Canvas. Parte 2. by Juan Carlos Saavedra (@jcsuscriptor) on CodePen.

Se tiene una falla, al momento de rotar el cuadrado con los triángulos, el eje de rotación es el vértice izquierdo superior, para corregir esto debemos realizar un traslado del eje según el valor del angulo, para lo cual utilizaremos translate.

See the Pen Juego - Canvas. Parte 2. 1 by Juan Carlos Saavedra (@jcsuscriptor) on CodePen.


En la "Hacer un Juego con HTML5 / Canvas. Parte 3.", vamos a completar el código para la caída del circulo y verificación si coincide el color del circulo con el color del triangulo superior.

Hacer un Juego con HTML5 / Canvas. Parte 1.


Voy a realizar un serie de post de crear un juego en html5, javascript, canvas. Según como avancen en los post, voy aumentando características hasta tener un juego final.

El juego que voy a realizar es un clon de Impossible Rush.

Parte. 1.

La primera parte consisten en crear las geometrías necesarias para el juego con instrucciones javascript en un elemento Canvas.

Se crea un circulo, y un cuadrado formado por 4 triángulos de 4 colores diferentes. Ver a continuación el código html, javascript y el resultado:


See the Pen Juego - Canvas. Parte 1. by Juan Carlos Saavedra (@jcsuscriptor) on CodePen.


Para aprender mas sobre canvas, pueden revisar el siguiente Tutorial Canvas

En la segunda parte, vamos a colocar la lógica para rotar el cuadrado al momento de dar un click.

Hacer un Juego con HTML5 / Canvas. Parte 2.

jueves, 27 de agosto de 2015

Comandos básicos Docker

Vamos a revisar algunos comandos básicos de docker,  utilizando como referencia mongodb.

Buscar imágenes:

  • docker search  

Este comando nos permite buscar imágenes en el  repositorio publico "Docker Hub", donde es una palabra relacionado con lo que estamos buscando ejemplo "ubuntu, mongo, mysql, apache, drupal, etc"

Ejemplo: Buscar imágenes existentes de mongodb.

  • docker search mongo 

Al ejecutar este comando se  visualiza un listado de elementos con la siguiente información:  "NAME, DESCRIPTION, STARTS, OFFICIAL, AUTOMATED"

Nombre, esta compuesto por /.  En el listado tenemos por ejemplo  "tutum/mongodb"  "torusware/speedus-mongo".

La columna OFFICIAL, nos permite determinar si la imagen es oficial, es este caso "mongo" es la imagen oficial de mongodb.

Figura 1. Docker search

Descargar imágenes:

  • docker pull

Este comando nos permite descargar una imagen por medio de su nombre, recuerde los nombres puede estar formados /

Ejemplo: Descargar imagen de mongo. En el anterior comando se detecto que el nombre de la imagen oficial de mongodb es "mongo", por lo tanto el comando es:

  • docker pull mongo 

Figura 2. Docker pull


Ejecutar imágenes
  • $ docker run
Este comando nos permite ejecutar un contenedor a partir de una imagen, existe varias opciones para este comando,

Ejemplo. Ejecutar un contenedor de drupal.

  • docker run -d drupal
Explicación:
  • run: comando para ejecutar contenedores. 
  • -d 
  • drupal: nombre de la imagen

Ejemplo. Ejecutar un conteneor de ubuntu, para interactuar con un shell utilizamos las opciones "-i -t" del comando "run"

  • $ docker run -i -t ubuntu /bin/bash 
Explicación:

  • run: comando para ejecutar contenedores. 
  • -i -t: opciones que nos permiten interactuar con el contenedor.
  •  ubuntu: nombre de la imagen. 
  • "/bin/bash": comando que se ejecuta en el contenedor en este caso iniciamos el shell bash para interactuar con el contenedor linux ubuntu


Figura 3. docker run -i -t ubuntu /bin/bash



Mayor información de run. https://docs.docker.com/reference/run/

Visualizar imágenes existentes localmente 
  • $ docker images 
Este comando visualiza un listado de las imágenes existente localmente.

Visualizar los contenedores que se encuentran ejecutándose. 
  • $ docker ps
Este comando visualiza un listado de los contenedores que están ejecutándose.




domingo, 16 de agosto de 2015

Comprender la Arquitectura de Docker


Docker es un proyecto de código abierto con el que fácilmente podremos crear "contenedores". Estos contenedores de Docker podríamos definirlos como máquinas virtuales ligeras, menos exigentes con los chips y memorias de los equipos donde se ejecutarán.

Docker Architecture Diagram
 

Docker utiliza una arquitectura cliente - servidor, el “Docker daemon” es el encargado de realizar el trabajo "construir, ejecutar y distribuir" los contenedores, el cliente permite interactuar con el servidor “Docker daemon”
 
El cliente y servidor se comunica vía socker o través de una API REST.
Para comprender docker, vamos a definir los tres componentes que lo conforman: 
  • Docker images.
  • Docker registries.
  • Docker containers.
Imágenes  Docker.

Las imágenes  docker son una especie de plantillas de solo lectura, las cuales contiene la información necesaria para ejecutar un contendedor. Una imagen puede tener el sistema
operativo Ubuntu, un servidor web apache con módulos de php, y una base de datos mysql.

Cada imagen inicia desde una imagen base, por ejemplo "Ubuntu image", "Fedora image". A esta imagen base se agrega otros componentes ejemplo una base de datos NoSQL "mongodb", node.js, etc.

En términos de programación son las clases.
 
Contenedor Docker. 

Un contenedor es creado a partir de una imagen, estos pueden ser ejecutados, detenidos, iniciados, eliminados.  Contiene todo lo necesario para que una aplicación pueda ejecutarse “Sistema operativo, aplicaciones, archivos, metadatos, procesos, etc.”

Cada contenedor es una plataforma aislada y segura, son autosuficientes (aunque pueden depender de otros contenedores, por ejemplo, un wordpress que necesita una base de datos mysql) no necesitando nada más que la imagen del contenedor para que funcionen los servicios que ofrece.

En términos de programación son las instancias “objetos” de las clases.
 
Registros Docker.

Los registros docker son repositorios que contienen las imágenes de los cuales se pueden descargar, agregar o actualizar. Estos permiten compartir las imágenes. Estos pueden ser públicos o privados.
 
El Registro Público de Docker es https://hub.docker.com/