social

Obtener imágenes de un enlace (al estilo Facebook) usando YQL, JSON y jQuery

(Ejemplo directo en: http://jsfiddle.net/4lberto/mGxGB/12/)

En Facebook, Google+ y otros sitios actuales es posible compartir un enlace a una página web con nuestros contactos. Una de las características de estos enlaces es que suelen aparecer con imágenes asociadas como ilustración del enlace. En este post veremos cómo podemos obtener en tiempo real las imágenes de un enlace cualquiera para mostrárselas a un usuario.

La herramienta principal que usaremos será YQL, abreviatura de Yahoo Query Language. Se trata de una utilidad que permite utilizar la potencia de análisis de datos de yahoo mediante una interfaz de comandos al estilo SQL, de modo que se evita tener que programar engorrosos métodos de parseo para tratar la información en formato Web.  Permite muchas otras utilidades.

La llamada a la herramienta YQL la realizaremos a través de una llamada AJAX de jQuery por ejemplo y obtendremos como respuesta un JSON con la información requerida. En nuestro caso le pasaremos al motor de YQL una URL y como salida esperaremos un JSON con todos los elementos img que cumplan las caracterísicas que hemos demandado.

YQL tiene una interfaz web donde se pueden programar la consultas al estilo de los clientes SQL para bases de datos relacionales. En esta interfaz podremos tanto programar la consulta y ver sus resultados como configurar el formato de salida. Para ello se accede a http://developer.yahoo.com/yql/ . El acceso a la consola de pruebas es: http://developer.yahoo.com/yql/console/

Nuestra consulta estará basada en la siguiente:


select * from html where url="http://www.engagdet.com" and xpath="//img"

Esta consulta nos devuelve todos los elementos img de la URL http://www.engagdet.com. Si seleccionamos el formato JSON, además de metainformación de la consulta, el resultado que obtenemos será algo similar al siguiente:

"results": {
"img": [
{
"alt": " Foto: BBC MUNDO",
"height": "305",
"src": "http://p2.trrsf.com/image/get?src=http%3A%2F%2Fimages.terra.com%2F2012%2F10%2F27%2F01-morgue.jpg&w=407&h=305&o=cf",
"title": " Foto: BBC MUNDO",
"width": "407"
},
{
"alt": " Foto: BBC MUNDO",
"height": "41",
"src": "http://p2.trrsf.com/image/get?src=http%3A%2F%2Fimages.terra.com%2F2012%2F10%2F27%2F01-morgue.jpg&w=55&h=41&o=cf",
"title": " Foto: BBC MUNDO",
"width": "55"
},
{
"alt": " Foto: DIFUSION",
"height": "41",
"src": "http://p2.trrsf.com/image/get?src=http%3A%2F%2Fimages.terra.com%2F2012%2F10%2F27%2F02-oxford.jpg&w=55&h=41&o=cf",
"title": " Foto: DIFUSION",
"width": "55"
},

Como dentro de una página Web existen multitud de imágenes y no todas ellas están relacionadas con el contenido, se puede filtrar por tamaños, por lo que podemos exigir un tamaño mínimo que nos  evite estas imágenes. Desgraciadamente diferenciar por el contenido es una operación inviable. También podemos ordenar los resultados por tamaño de modo que los primeros sean los mayores. Es probable que las imágenes más grandes de una página Web sean las que acompañan a la noticia. Desafortunadamente aquellas foto que no tengan un tamaño específicos en los atributos width y height de img no podrán ser catalogadas.

La consulta con estas condiciones aparece a continuación:


select * from html where url="http://www.terra.com" and xpath="//img" and width>60 | sort(field='width', descending='true')
<pre>

Finalmente configuraremos el resultado en formato JSON que es lo que vamos a analizar con la llamada AJAX de jQuery. Tomamos la URL de llamada que nos indica YQL. La podemos encontrar en la zona inferior de la consola de YQL. En nuestro ejemplo la URL de llamada será la siguiente (* contiene saltos de línea para que sea legible) :


http://query.yahooapis.com/v1/public/yql?
q=select%20*%20from%20html%20where%20url%3D%22http%3A%2F%2F
www.terra.com%22%20and%20xpath%3D%22%2F%2Fimg%22%20and%20
width%3E60%20%7C%20sort(field%3D'width'%2C%20descending%3D'true')

Una vez tenemos la consulta hecha y probada ejecutando la URL en el navegador y probando la salida en servicios como http://json.parser.online.fr/, podemos pasar a programar la parte de Javascript con jQuery.

Tenemos que tener en cuenta de que se trata de una llamada AJAX a un dominio diferente al de residencia del Javascript. Este tema ya se trató en otro post de este blog (https://mysticalpotato.wordpress.com/2010/11/18/jsonp-salvando-la-limitacion-de-dominio-de-xhr-cuando-se-hace-cross-scripting-xss/). jQuery soluciona fácilmente esto añadiendo un parámetro de callback que completa automáticamente.

También habrá que parametrizar la URL del enlace. Para ello tenemos un formulario cualquiera con un input con id=”input_web”. Mejor lo vemos en código fuente:


function procesa_web() {

var url_web = $("#input_web").val()
//console.log("Valor completo:" + url_web);

$("#resultado").html("");

$.ajax({
url: 'http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22' + escape(url_web) + '%22%20and%0A%20%20%20%20%20%20
xpath%3D"%2F%2Fimg"%20and%20width%3E35%20and%20
height%3E35&format=json&diagnostics=true&callback=?',
async: false,
cache: false,
dataType: 'json',
success: function(data) {
imagenes_from_web = data.query.results.img; //asignamos a la variable global
var salida = "<b>Imágenes de Web</b><br />";
salida += "<a href=\"javascript:void(0);\" onclick=\"javascript:prev_image()\">Anterior</a>&nbsp;|&nbsp;";
salida += "<a href=\"javascript:void(0);\" onclick=\"javascript:next_image()\">Siguiente</a><br />";
salida += "<img id=\"img_from_web\" data-contador=\"0\" src=\"" + imagenes_from_web[0].src + "\"/>";

$('#resultado').html(salida);
}
});
}

Como se puede ver se lee el valor de la URL a procesar del input en la variable url_web y se escapa para incluirla en la URL. Adicionalmente se incluye el parámetro callback=? para salvar el cross-domain indicado anteriormente.

Los parámetros de AJAX son los utilizados en otros post: síncrono, sin caché porque son datos dinámicos y el tipo de datos JSON.

Dentro del sucess de la llamada AJAX se procesa el resultado. En primer lugar tomamos los valores obtenidos en el JSON para asignarlos a una variable global a la página que será compartida por todas las funciones.  Obviamente navegamos por el JSON para sacar sólo el listado de imágenes:

</pre>
imagenes_from_web = data.query.results.img

Posteriormente pintamos en la capa resultado la primera imagen y dos botones que permitirán navegar por las imágenes. Estos dos botones hacen referencia a dos funciones que no hacen otra cosa que ir refrescando el contenido de la imagen que se muestra en ese momento con el de la siguiente o la anterior del vector global a la página que almacena el resultado. Nótese que en el tag img dejamos el atributo data-contador para almacenar el índice del vector de imágenes. La posibilidad de incluir atributos para datos es una de las posibilidades que ofrece HTML5 (http://html5doctor.com/html5-custom-data-attributes/). Las funciones para navegar por las fotos son las siguientes:


function next_image() {

var contador = parseInt($('#img_from_web').attr("data-contador"));
contador++;
var url_imagen = imagenes_from_web[contador].src;

$('#img_from_web').attr("src", url_imagen);
$('#img_from_web').attr("data-contador", contador);
}

function prev_image() {

var contador = parseInt($('#img_from_web').attr("data-contador"));
contador--;
$('#img_from_web').attr("src", imagenes_from_web[contador].src);
$('#img_from_web').attr("data-contador", contador);
}​

El ejemplo acaba aquí, pero si queréis incluirlo al estilo Facebook para una noticia, simplemente, en el momento de que el usuario confirme el enlace, se tomará el índice del vector de imágenes y se leerá la URL para asignarla a un formulario o llamada AJAX.

El ejemplo completo y funcional podéis visitarlo en: http://jsfiddle.net/4lberto/mGxGB/12/

Control de la Reputación en las Redes Sociales

En esta ocasión voy a exponer algunos enlaces para la monitorización de la reputación online que he aprendido en el curso de Gestión de Comunidades Virtuales del MBA que estoy haciendo en CEPADE. Gracias al profesor. Pablo Martínez por sus apuntes 🙂

En los últimos años se ha confirmado que Internet es un lugar en el que hacer marketing. Todas las empresas, incluyendo las tradicionales, se están teniendo que ver obligadas a tener presencia en este medio,pasando a formar parte de su estrategia comunicativa, especialmente desde la aparición de las redes sociales. Las redes sociales son la nueva forma de entender Internet, un lugar donde las marcas pueden promocionarse y encontrar un fantástico altavoz para difundir sus marcas como nunca antes había sucedido.

En las redes sociales, son los usuarios los que controlan los mensajes, cómo fluye la información. El paso de información normalmente se basa en una forma tecnificada del boca a boca, donde hay generadores de opinión en casi cualquier lugar. Se puede hablar de la “marca” en cualquier parte de la red, por lo que es necesario realizar un seguimiento o monitorización de las opiniones que existen en la red.

El seguimiento permitirá tener un conocimiento de qué opina la red acerca de nuestra marca (personal o comercial), con el fin de poder adaptar las estrategias comunicativas para lograr una mejor imagen.

Se trata de una tarea compleja, ya que a veces es complicado encontrar toda las menciones en todas las redes sociales. Esto conlleva una gran cantidad de tiempo y requiere de un conocimiento excepcional de los lugares de Internet que son susceptibles de congregar a usuarios opinando de nuestra marca.

Afortunadamente existen herramientas que pueden ayudarnos en esta tarea de monitorizar. Estas herramientas, básicamente utilizan los motores de búsqueda de Internet y las API que exponen la información pública de las publicaciones de las redes sociales para hacer informes automáticos de las menciones de una marca en Internet. Algunas de ellas se atreven, mediante el uso de IA, a interpretar los comentarios y a obtener métricas sobre lo social que es una marca.

Hay un gran número de estas herramientas, las que he encontrado más útiles, además del uso avanzado de buscadores como Google, Google Trends y similares, son: