7.3 JSON y XML

Existe una web para humanos (el mundo del HTML) y otra para máquinas. Se puede bajar información programáticamente de las primeras usando las técnicas de rascado (o scraping) discutidas más arriba y después limpiarla para su postproceso como hemos hecho en la sección anterior.

Pero cada vez son más populares los servicios web que proporcionan información a través de APIs que son consultadas directamente por ordenadores. Estos servicios suelen proporcionar resultados en formato JSON, XML o ambos. Los dos formatos son similares: organizan la información en forma de árbol.

Por ejemplo, el INE proporciona un API JSON del que se puede bajar información de interés estadístico. Tiene, además, un servicio que permite construir la consulta, i.e., obtener la URL con la que consultar una serie de datos en concreto. Usándola, encontramos que para obtener la población de cada provincia española por sexos durante los últimos cinco años tenemos que consultar esta.

Pero podemos realizar la consulta programáticamente así:

library(rjson)

pob <- readLines("http://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/2852?nult=5&tip=AM")
pob <- paste(pob, collapse = " ")
pob <- fromJSON(pob)

En la primera línea cargamos el paquete necesario, rjson. En las dos siguientes leemos la URL y colapsamos todas las líneas en una única cadena de texto, una exigencia de fromJSON. Esta es la función que llamamos en última instancia para convertir el fichero JSON en una estructura arborescente en R, i.e., una lista que contiene, a su vez, otras listas.

class(pob)
## [1] "list"
length(pob)
## [1] 159

pob tiene longitud 159. Son tres elementos por cada provincia (más Ceuta, Melilla y el total nacional), los correspondientes a los dos sexos y el total. Cada uno de estos elementos tiene una serie de atributos y una sublista de longitud 5, que almacena los datos anuales. Así,

pob[[89]]$Data[[5]]$Valor
## [1] 168013

es el valor (i.e, la población) correspondiente al quinto periodo (o año) del elemento 85 de la primera lista, i.e.,

pob[[89]]$Nombre
## [1] "Lugo. Hombres. Total habitantes. Personas. "

Idealmente, querríamos convertir nuestros datos (o la parte más relevante de ellos) en una tabla para su posproceso. Podremos hacerlo más adelante, cuando aprendamos más sobre manipulación de datos y programación en R.

Otras APIs proporcionan información en formato XML. Por ejemplo, la del Banco Mundial25:

library(xml2)

bm  <- read_xml("http://api.worldbank.org/countries/all/indicators/NY.GDP.MKTP.CD?date=2009:2010&per_page=500&page=1")
esp <- xml_find_all(bm, "//*/wb:data[wb:country[@id='ES']]/wb:value")
as.numeric(xml_text(esp))
## [1] 1.431617e+12 1.499100e+12

El código anterior proporciona el PIB español de los años 2009 y 2010 en dólares. La primera línea carga el paquete xml2, que es el que vamos a usar para leer ficheros XML. La función read_xml lee una URL de la API del Banco Mundial que extrae el indicador NY.GDP.MKTP.CD (PIB según la documentación de la API) y la procesa. A diferencia de lo que ocurría con JSON, el objeto bm no es una lista de R (aunque la podemos convertir en una usando la función as_list), sino un objeto de la clase xml_document. Sobre este documento se pueden realizar consultas usando XPath, como más arriba, y obtener los valores corespondientes al país con etiqueta ES, es decir, España.

El objeto esp contiene dos nodos y la función xml_text permite extraer su contenido (en formato de texto, que tenemos que convertir en números). En general, los nodos tienen atributos y el texto es uno más de ellos.


  1. Que también la ofrece en JSON.