una tabla seleccionar pagina limpieza filas extraer eliminar datos con como html xml r web-scraping rcurl

html - seleccionar - Raspado de datos de tablas en múltiples páginas web en R(jugadores de fútbol)



rvest vignette (1)

A continuación, le mostramos cómo puede obtener fácilmente todos los datos en todas las tablas en todas las páginas de los jugadores ...

Primero haz una lista de las URL para todas las páginas de los jugadores ...

require(RCurl); require(XML) n <- length(letters) # pre-allocate list to fill links <- vector("list", length = n) for(i in 1:n){ print(i) # keep track of what the function is up to # get all html on each page of the a-z index pages inx_page <- htmlParse(getURI(paste0("http://www.sports-reference.com/cfb/players/", letters[i], "-index.html"))) # scrape URLs for each player from each index page lnk <- unname(xpathSApply(inx_page, "//a/@href")) # skip first 63 and last 10 links as they are constant on each page lnk <- lnk[-c(1:63, (length(lnk)-10):length(lnk))] # only keep links that go to players (exclude schools) lnk <- lnk[grep("players", lnk)] # now we have a list of all the URLs to all the players on that index page # but the URLs are incomplete, so let''s complete them so we can use them from # anywhere links[[i]] <- paste0("http://www.sports-reference.com", lnk) } # unlist into a single character vector links <- unlist(links)

Ahora tenemos un vector de aproximadamente 67,000 URL (parece que hay muchos jugadores, ¿puede ser así?), Entonces:

En segundo lugar, raspe todas las tablas en cada URL para obtener sus datos, así:

# Go to each URL in the list and scrape all the data from the tables # this will take some time... don''t interrupt it! # start edit1 here - just so you can see what''s changed # pre-allocate list all_tables <- vector("list", length = (length(links))) for(i in 1:length(links)){ print(i) # error handling - skips to next URL if it gets an error result <- try( all_tables[[i]] <- readHTMLTable(links[i], stringsAsFactors = FALSE) ); if(class(result) == "try-error") next; } # end edit1 here # Put player names in the list so we know who the data belong to # extract names from the URLs to their stats page... toMatch <- c("http://www.sports-reference.com/cfb/players/", "-1.html") player_names <- unique (gsub(paste(toMatch,collapse="|"), "", links)) # assign player names to list of tables names(all_tables) <- player_names

El resultado se ve así (esto es solo un fragmento de la salida):

all_tables $`neli-aasa` $`neli-aasa`$defense Year School Conf Class Pos Solo Ast Tot Loss Sk Int Yds Avg TD PD FR Yds TD FF 1 *2007 Utah MWC FR DL 2 1 3 0.0 0.0 0 0 0 0 0 0 0 0 2 *2010 Utah MWC SR DL 4 4 8 2.5 1.5 0 0 0 1 0 0 0 0 $`neli-aasa`$kick_ret Year School Conf Class Pos Ret Yds Avg TD Ret Yds Avg TD 1 *2007 Utah MWC FR DL 0 0 0 0 0 0 2 *2010 Utah MWC SR DL 2 24 12.0 0 0 0 0 $`neli-aasa`$receiving Year School Conf Class Pos Rec Yds Avg TD Att Yds Avg TD Plays Yds Avg TD 1 *2007 Utah MWC FR DL 1 41 41.0 0 0 0 0 1 41 41.0 0 2 *2010 Utah MWC SR DL 0 0 0 0 0 0 0 0 0

Finalmente, digamos que solo queremos ver las tablas de paso ...

# just show passing tables passing <- lapply(all_tables, function(i) i$passing) # but lots of NULL in here, and not a convenient format, so... passing <- do.call(rbind, passing)

Y terminamos con un marco de datos que está listo para análisis adicionales (también solo un fragmento) ...

Year School Conf Class Pos Cmp Att Pct Yds Y/A AY/A TD Int Rate james-aaron 1978 Air Force Ind QB 28 56 50.0 316 5.6 3.6 1 3 92.6 jeff-aaron.1 2000 Alabama-Birmingham CUSA JR QB 100 182 54.9 1135 6.2 6.0 5 3 113.1 jeff-aaron.2 2001 Alabama-Birmingham CUSA SR QB 77 148 52.0 828 5.6 4.3 4 6 99.8

Estoy trabajando en un proyecto para la escuela en el que necesito recopilar las estadísticas de carrera de los jugadores de fútbol de la NCAA. Los datos para cada jugador están en este formato.

http://www.sports-reference.com/cfb/players/ryan-aplin-1.html

No puedo encontrar un conjunto de todos los jugadores, así que tengo que ir página por página y sacar la fila inferior de cada una de las tablas de puntaje de precipitación y recepción etc. html

Cada jugador está catagorizado por su apellido con enlaces a cada alfabeto que va aquí.

http://www.sports-reference.com/cfb/players/

Por ejemplo, cada jugador con el apellido A se encuentra aquí.

http://www.sports-reference.com/cfb/players/a-index.html

Esta es la primera vez que me dedico realmente al análisis de datos, así que traté de encontrar preguntas similares con respuestas. La respuesta más cercana que encontré fue esta pregunta

Creo que podría usar algo muy similar donde cambio el número de página con el nombre del jugador recolectado. Sin embargo, no estoy seguro de cómo cambiarlo para buscar el nombre del jugador en lugar del número de página.

Samuel L. Ventura también dio una charla sobre el raspado de datos para datos de la NFL recientemente que se puede encontrar aquí .

EDITAR:

Ben fue realmente útil y proporcionó un gran código. La primera parte funciona muy bien, sin embargo, cuando intento ejecutar la segunda parte me encuentro con esto.

> # unlist into a single character vector > links <- unlist(links) > # Go to each URL in the list and scrape all the data from the tables > # this will take some time... don''t interrupt it! > all_tables <- lapply(links, readHTMLTable, stringsAsFactors = FALSE) Error in UseMethod("xmlNamespaceDefinitions") : no applicable method for ''xmlNamespaceDefinitions'' applied to an object of class "NULL" > # Put player names in the list so we know who the data belong to > # extract names from the URLs to their stats page... > toMatch <- c("http://www.sports-reference.com/cfb/players/", "-1.html") > player_names <- unique (gsub(paste(toMatch,collapse="|"), "", links)) Error: cannot allocate vector of size 512 Kb > # assign player names to list of tables > names(all_tables) <- player_names Error: object ''player_names'' not found > fix(inx_page) Error in edit(name, file, title, editor) : unexpected ''<'' occurred on line 1 use a command like x <- edit() to recover In addition: Warning message: In edit.default(name, file, title, editor = defaultEditor) : deparse may be incomplete

Esto podría ser un error debido a que no tengo suficiente memoria (solo 4 GB en la computadora que estoy usando actualmente). Aunque no entiendo el error

> all_tables <- lapply(links, readHTMLTable, stringsAsFactors = FALSE) Error in UseMethod("xmlNamespaceDefinitions") : no applicable method for ''xmlNamespaceDefinitions'' applied to an object of class "NULL"

Mirando a través de mis otros conjuntos de datos, mis jugadores realmente solo se remontan a 2007. Si hubiera alguna forma de atraer a solo personas a partir de 2007, eso podría ayudar a reducir los datos. Si tuviera una lista de personas cuyos nombres quería quitar podría reemplazar el LNK en

links[[i]] <- paste0("http://www.sports-reference.com", lnk)

con solo los jugadores que necesito?