Cómo obtener el estado de varios sitios web usando la técnica de scraping y R. Se recorren un listado de URL, se accede y se leen las cabeceras HTTP, para obtener el estado (status) de cada una de ellas.
- Requisitos para hacer scraping con R.
- Obtener estado de varias URL usando la cabecera HTML status con R.
Requisitos para hacer scraping con R
El requisito único será disponer de R y RStudio, así como de sus librerías básicas. En el siguiente artículo explicamos cómo instalar R, RStudio y sus librerías básicas:
Para la técnica de scraping con R, necesitaremos instalar en R Studio las siguientes librerías: httr. Podremos instalarlas, desde RStudio, ejecutando los siguientes comandos:
1 |
install.packages("httr"); |
Obtener estado de varias URL usando la cabecera HTML status con R
Se pretende obtener el estado de varias URL (sitios web), que vendrán dados en una variable de tipo data frame. Se recorrerán todos los elementos de esta variable y se obtendrá una nueva tabla con el resultado obtenido por cada URL.
En primer lugar, haremos una prueba para obtener las cabeceras HTTP de una web. Para ello usaremos la librería httr:
1 |
library(httr); |
Para obtener el encabezado HTTP de la web https://www.mediawiki.org/wiki/MediaWiki, usaremos:
1 |
HEAD("https://www.mediawiki.org/wiki/MediaWiki"); |
Que nos devolverá las etiquetas de la cabecera HTTP de la web, entre otras:
- Date: fecha y hora del servidor de la web.
- Status: código de estado de la web. El estado 200 indica OK.
- Content-Type: tipo de contenido de la web.
- Charset: juego de caracteres de la web.
En este estudio, usaremos la etiqueta «status» para comprobar si la web está disponible o no.
Vamos a obtener únicamente el valor de «status», para ello, guardaremos el resultado obtenido anteriormente en la variable rs, con:
1 2 |
rs <- HEAD("https://www.mediawiki.org/wiki/MediaWiki"); rs$status_code; |
Nos devolverá: 200.
Para obtener una varable data frame con un listado de URL a visitar, usaremos los enlaces obtenidos en este tutorial:
En el tutorial anterior explicamos cómo generar una variable data frame con una lista de URL obtenida de un sitio web. Usaremos esta misma lista para hacer el análisis de cada URL.
En el tutorial quedó una lista del estilo:
Para poder hacer scraping de cada URL, en primer lugar tendremos que prepararlas. Prepararemos la tabla de enlaces, haciendo los siguientes procesos:
- Si no tiene http o https, será porque es una url relativa, por lo que añadimos el dominio, en nuestro caso: .
- Si tiene # será un enlace a la misma página del dominio, por lo que añadimos el dominio.
- Si tiene http o https será porque es un enlace a web externa, en este caso no hacemos nada pues ya tenemos la URL completa.
Para hacer este proceso, en primer lugar, guardaremos el dominio raíz a usar en la variable «dominio»:
1 |
dominio <- "https://www.mediawiki.org/wiki/MediaWiki"; |
Obtenemos un subconjunto de URL que no tiene http o https en la variable sinHTTP, teniendo en cuenta que dfEnlacesSDup y urlEnlacesV son dos variables obtenidas en este tutorial.
1 |
sinHTTP <- subset(dfEnlacesSDup[!grepl("http|https", dfEnlacesSDup$urlEnlacesV), ]); |
Obtenemos un data frame concatenando el dominio a las URL anteriores, sinHTTPArreglados:
1 |
sinHTTPArreglados <- lapply(sinHTTP$urlEnlacesV, function(x) paste(dominio,x,sep="")); |
Como el anterior comando devuelve una lista, la agregamos al data frame sinHTTP, reemplazando la columna “urlEnlacesV”:
1 |
sinHTTP$urlEnlacesV <- sinHTTPArreglados; |
Obtenemos un subconjunto de URL que sí tienen http o https, para unir ambos:
1 |
conHTTP <- subset(dfEnlacesSDup[grepl("http|https", dfEnlacesSDup$urlEnlacesV), ]); |
Unimos ambos data frames (sinHTTP y conHTT):
1 |
visitarHTTP <- rbind(conHTTP, sinHTTP); |
Quedando una tabla como la siguiente:
Pretendemos acceder a cada URL de la tabla visitarHTTP y guardar dos valores por cada URL:
- Visitada: si se ha accedido.
- Estado: el valor de la etiqueta status de la cabecera HTTP de cada URL.
Por ello, añadiremos estas dos columnas a la tabla visitarHTTP:
1 2 |
visitarHTTP["visitada"] <- 0; visitarHTTP["estado"] <- 0; |
Creamos una función para recorrer el data frame y obtener el encabezado de cada URL. Esta función visitará cada URL, obteniendo su estado, devolverá el data frame pasado por argumento con el resultado de la comprobación de cada URL, incrementando el número de visitas (visitada):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
comprobarEstado <- function(df) { #Para depurar y no tener que visitar todos los enlaces #j = 0; for (i in 1:nrow(df)) { #Para depurar y no tener que visitar todos los enlaces #j <- j + 1; url = df$urlEnlacesV[i]; #Una URL tendrá al menos 4 caracteres a.aa if (nchar(url) > 3) { #Para depurar y no tener que visitar todos los enlaces #if (j == 5) # break; tryCatch({ resultado <- HEAD(as.character(url)); print(paste("Estado --- ", resultado$status_code)); df$estado[i] <- resultado$status_code; #Para depuración, para mostrar resultado print(paste(url, resultado$status_code, sep = "->")); }, error = function(e) { #Ha habido algún error al obtener el estado, se añade 0 df$estado[i] <- 0; #Para depurar, mostrar el error print(paste(url, e, sep = "->"))}); #Esperamos 10 segundos entre cada petición #Para no generar tráfico excesivo y no ser baneados Sys.sleep(10); } else { #La URL no es correcta, se añade 0 al estado df$estado[i] <- 0; } #Incrementamos las visitas a la URL df$visitada[i] <- df$visitada[i] + 1; } #Devolvemos el data frame con el resultado return(df); } |
Ejecutamos la función comprobarEstado para que devuelva el data frame en dfResultadoFinal. La primera vez le pasaremos como argumento el data frame «visitarHTTP». Las siguientes veces, para que sume las visitas (vistas), le pasaremos el propio dataframe dfResultadoFinal. Antes de ejecutar la consulta, conviene indicar que si tenemos muchas URL, el proceso puede tardar varios minutos, dado que se demorará 10 segundos por cada URL más el tiempo que tarde en acceder a cada una de ellas:
1 |
dfResultadoFinal <- comprobarEstado(visitarHTTP); |
El proceso irá mostrando la URL scrapeada (visitada) y el resultado obtenido:
Volvemos a ejecutar la función, pero esta vez pasando como argumento el data frame dfResultadoFinal, de forma que sume el número de veces que se ha visitado la web:
1 |
dfResultadoFinal <- comprobarEstado(dfResultadoFinal); |
Si mostramos el contenido de dfResultadoFinal, obtendremos todos los datos recabados (URL, visitas, estado):
1 |
View(dfResultadoFinal); |