martes, 19 de septiembre de 2017

Web scrapping con R y Postgresql

El paquete rvest de R que permite hacer web scrapping (acceder al DOM de una página web) y leer los datos que ésta contiene; para utilizarlos según se requiera.
El web scrapping es útil para extraer datos que se actualizan en la red en diferentes sitios, algunos ejemplos son: tipo de cambio, el clima, semana ISO actual, datos financieros, etc.
En este caso descargaré los datos de códigos de paises ISO (ISO Country codes) de la página w3schools.com y los guardaré en una tabla de Postgresql
Este es un extracto de los códigos:
Un punto clave del scrapping es identificar los elementos de las páginas, en este caso hay que buscar la tabla que contiene los códigos de los paises. Al ver código fuente de la página:
Se identifica el siguiente elemento TABLE:
<table class="w3-table-all notranslate">
Para extraer los datos usando el paquete rvest es necesario tener el url de la página y los elementos DOM de los cuales leer los datos. A continuación está el código R para guardar los datos en un Dataframe.
library("rvest")

url = 'https://www.w3schools.com/tags/ref_country_codes.asp'
countries = html(url, enconding = "UTF-8")

countriesDF = countries %>%
html_nodes("table") %>%
.[[1]] %>%
html_table()

La función html_nodes() extrae todas las tablas contenidas en el documento. En el ejemplo solo hay una y por eso se accede mediante .[[1]]
La función html_table() convierte la tabla a un dataframe de R.
El script para crear la tabla en Postgresql:
CREATE TABLE country(
    country_id CHAR(2) NOT NULL PRIMARY KEY,
    country VARCHAR(200) NOT NULL UNIQUE    
);
Finalmente usé los paquetes dplyr, para renombrar las columnas y filtrar los que no tienen código, y RPostgreSQL para guardar los códigos ISO y paises en la tabla country:
library("dplyr")
library("RPostgreSQL")

drv = dbDriver("PostgreSQL")
con = dbConnect(
    drv, dbname = "tuBaseDeDatos",
    host = "tuHostOIP", port = 5432,
    user = "tuUsuario", password = "tuPassword")
    
dbWriteTable(
    con, "country", 
    value = select(countriesDF, country_id = "ISO Code", country = Country) %>%
        filter(!is.na(country_id)), 
    append = TRUE, row.names = FALSE)
 
 dbDisconnect(con)
El script completo en R:
# Se usa para web scraping
library("rvest")
# Se usa para renombrar y filtrar datos
library("dplyr")
# Guarda en base de datos
library("RPostgreSQL")


# Web scrapping

url = 'https://www.w3schools.com/tags/ref_country_codes.asp'
countries = html(url, enconding = "UTF-8")

countriesDF = countries %>%
html_nodes("table") %>%
.[[1]] %>%
html_table()


# Guardado a BD

drv = dbDriver("PostgreSQL")
con = dbConnect(
    drv, dbname = "tuBD",
    host = "tuHostOIP", port = 5432,
    user = "tuUsuario", password = "tuPassword")
    
dbWriteTable(
    con, "country", 
    value = select(countriesDF, country_id = "ISO Code", country = Country) %>%
        filter(!is.na(country_id)), 
    append = TRUE, row.names = FALSE)
 
dbDisconnect(con)