2012-07-29 11 views
12

Parece que el sitio web está bloqueando el acceso directo desde Curl.Descarga de datos de medallas olímpicas en vivo en R

library(XML) 
library(RCurl) 
theurl <- "http://www.london2012.com/medals/medal-count/" 
page <- getURL(theurl) 

page # fail 
[1] "<HTML><HEAD>\n<TITLE>Access Denied</TITLE>\n</HEAD><BODY>\n<H1>Access Denied</H1>\n \nYou don't have permission to access \"http&#58;&#47;&#47;www&#46;london2012&#46;com&#47;medals&#47;medal&#45;count&#47;\" on this server.<P>\nReference&#32;&#35;18&#46;358a503f&#46;1343590091&#46;c056ae2\n</BODY>\n</HTML>\n" 

Tratemos de ver si podemos acceder directamente desde la Tabla.

page <- readHTMLTable(theurl) 

no hay suerte Error in htmlParse(doc) : error in creating parser for http://www.london2012.com/medals/medal-count/

¿Cómo ir sobre cómo obtener esta tabla en R?


Actualización: en respuesta a los comentarios y toying, simular una cadena de agente de usuario trabajó para obtener el contenido. Pero readHTMLtable devuelve un error.

page <- getURLContent(theurl, useragent="Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2") 
+0

Lynx, parece estar bloqueado también. –

+0

Dado que la página se carga en Firefox, ¿ves la fuente y la guardas en el disco? –

+0

Con getURL puede especificar una cadena de agente de usuario falso, que funcionó para obtener los datos. Pero readHTMLTable todavía no se desprende muy bien. Devuelve un error ('Error en los nombres (ans) = encabezado: el atributo' nombres '[13] debe tener la misma longitud que el vector [7] ') no está muy seguro de cómo depurar eso. –

Respuesta

12

Parece que esto funciona:

rr <- readHTMLTable(page,header=FALSE) 
rr2 <- setNames(rr[[1]], 
       c("rank","country","gold","silver","bronze","junk","total")) 
rr3 <- subset(rr2,select=-junk) 
## oops, numbers all got turned into factors ... 
tmpf <- function(x) { as.numeric(as.character(x)) } 
rr3[,-2] <- sapply(rr3[,-2],tmpf)    
head(rr3) 
## rank        country gold silver bronze total 
## 1 1    People's Republic of China 6  4  2 12 
## 2 2    United States of America 3  5  3 11 
## 3 3         Italy 2  3  2  7 
## 4 4      Republic of Korea 2  1  2  5 
## 5 5         France 2  1  1  4 
## 6 6 Democratic People's Republic of Korea 2  0  1  3 
with(rr3,dotchart(total,country)) 
+0

Creo puede usar 'stringsAsFactors = FALSE' en la llamada' readHTMLTable'. – GSee

+0

OK, pero creo que todavía tendría que convertir esas columnas a numéricas. –

+0

¿Acabas de mirar el código para ver si tenía 'thead'? –

12

Esto es lo que ocurrió con el uso de expresiones regulares. Muy específico y definitivamente no mejor que usar readHTMLTable utilizado en la otra respuesta. Más para mostrar que se puede ir muy lejos con minería de textos en I:

# file <- "~/Documents/R/medals.html" 
# page <- readChar(file,file.info(file)$size) 

library(RCurl) 
theurl <- "http://www.london2012.com/medals/medal-count/" 
page <- getURLContent(theurl, useragent="Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20120716 Firefox/15.0a2") 


# Remove html tags: 
page <- gsub("<(.|\n)*?>","",page) 
# Remove newlines and tabs: 
page <- gsub("\\n","",page) 

# match table: 
page <- regmatches(page,regexpr("(?<=Total).*(?=Detailed)",page,perl=TRUE)) 

# Extract country+medals+rank 
codes <-regmatches(page,gregexpr("\\d+[^\\r]*\\d+",page,perl=TRUE))[[1]] 
codes <- codes[seq(1,length(codes)-2,by=2)] 

# Extract country and medals: 
Names <- gsub("\\d","",codes) 
Medals <- sapply(regmatches(codes,gregexpr("\\d",codes)),function(x)x[(length(x)-2):length(x)]) 

# Create data frame: 
data.frame(
    Country = Names, 
    Gold = as.numeric(Medals[1,]), 
    Silver = as.numeric(Medals[2,]), 
    Bronze = as.numeric(Medals[3,])) 

Y la salida:

        Country Gold Silver Bronze 
1    People's Republic of China 6  4  2 
2    United States of America 3  5  3 
3         Italy 2  3  2 
4      Republic of Korea 2  1  2 
5         France 2  1  1 
6 Democratic People's Republic of Korea 2  0  1 
7        Kazakhstan 2  0  0 
8        Australia 1  1  1 
9         Brazil 1  1  1 
10        Hungary 1  1  1 
11       Netherlands 1  1  0 
12      Russian Federation 1  0  3 
13        Georgia 1  0  0 
14       South Africa 1  0  0 
15         Japan 0  2  3 
16       Great Britain 0  1  1 
17        Colombia 0  1  0 
18         Cuba 0  1  0 
19         Poland 0  1  0 
20        Romania 0  1  0 
21    Taipei (Chinese Taipei) 0  1  0 
22        Azerbaijan 0  0  1 
23        Belgium 0  0  1 
24         Canada 0  0  1 
25     Republic of Moldova 0  0  1 
26         Norway 0  0  1 
27         Serbia 0  0  1 
28        Slovakia 0  0  1 
29        Ukraine 0  0  1 
30        Uzbekistan 0  0  1 
+0

+1 para las habilidades de expresión regular. Aunque lo uso regularmente, todavía estoy en gran parte desconcertado por ello. –

+1

Por supuesto, siempre es una buena habilidad tener: http://xkcd.com/208/ –