2017-05-27 2 views
0

J'essaie de gratter les données de a website en utilisant R. J'utilise rvest pour essayer de reproduire an example scraping the IMDB page for the Lego Movie. L'exemple préconise l'utilisation d'un outil appelé Selector Gadget pour faciliter l'identification du html_node associé aux données que vous cherchez à extraire.Grattage Web avec R et gadget de sélection

Je suis finalement intéressé par la construction d'une trame de données qui a le schéma/colonnes suivantes: rank, blog_name, facebook_fans, twitter_followers, alexa_rank.

Mon code ci-dessous. J'ai pu utiliser Selector Gadget pour identifier correctement la balise html utilisée dans l'exemple Lego. Cependant, en suivant le même processus et la même structure de code que l'exemple de Lego, j'obtiens NAs (...using firstNAs introduced by coercion[1] NA ). Mon code est ci-dessous:

data2_html = read_html("http://blog.feedspot.com/video_game_news/") 
data2_html %>% 
    html_node(".stats") %>% 
    html_text() %>% 
    as.numeric() 

J'ai aussi expérimenté: html_node("html_node(".stats , .stats span")), qui semble fonctionner pour la « fans Facebook » colonne car il rapporte 714 matches, mais retourne seulement 1 numéro est retourné.

714 matches for .//*[@class and contains(concat(' ', normalize-space(@class), ' '), ' stats ')] | .//*[@class and contains(concat(' ', normalize-space(@class), ' '), ' stats ')]/descendant-or-self::*/span: using first{xml_node} 
<td> 
[1] <span>997,669</span> 

Répondre

2

Cela peut vous aider:

library(rvest) 

d1 <- read_html("http://blog.feedspot.com/video_game_news/") 

stats <- d1 %>% 
    html_nodes(".stats") %>% 
    html_text() 

blogname <- d1%>% 
    html_nodes(".tlink") %>% 
    html_text() 

Notez qu'il est html_nodes (pluriel)

Résultat:

> head(blogname) 
[1] "Kotaku - The Gamer's Guide" "IGN | Video Games"   "Xbox Wire"     "Official PlayStation Blog" 
[5] "Nintendo Life "    "Game Informer" 

> head(stats,12) 
[1] "997,669" "1,209,029" "873"  "4,070,476" "4,493,805" "399"  "23,141,452" "10,210,993" "879"  
[10] "38,019,811" "12,059,607" "500" 

blogname renvoie la liste des noms de blog qui est facile gérer. D'un autre côté, l'information sur les statistiques est mitigée. Cela est dû à la façon dont la classe stats pour les fans de Facebook et Twitter sont indiscernables les uns des autres. Dans ce cas, le tableau de sortie a l'information tous les trois chiffres, c'est à dire stats = c (fb, tw, alx, fb, tw, alx ...). Vous devriez séparer chaque vecteur de celui-ci.

FBstats = stats[seq(1,length(stats),3)] 

> head(stats[seq(1,length(stats),3)]) 
[1] "997,669" "4,070,476" "23,141,452" "38,019,811" "35,977"  "603,681" 
0

Il utilise html_nodes (pluriel) et str_replace pour supprimer des virgules en nombre. Je ne sais pas si ce sont toutes les statistiques dont vous avez besoin.

library(rvest) 
library(stringr) 
data2_html = read_html("http://blog.feedspot.com/video_game_news/") 
data2_html %>% 
    html_nodes(".stats") %>% 
    html_text() %>% 
    str_replace_all(',', '') %>% 
    as.numeric() 
1

Vous pouvez utiliser html_table pour extraire toute la table avec un minimum de travail:

library(rvest) 
library(tidyverse) 

# scrape html 
h <- 'http://blog.feedspot.com/video_game_news/' %>% read_html() 

game_blogs <- h %>% 
    html_node('table') %>% # select enclosing table node 
    html_table() %>% # turn table into data.frame 
    set_names(make.names) %>% # make names syntactic 
    mutate(Blog.Name = sub('\\s?\\+.*', '', Blog.Name)) %>% # extract title from name info 
    mutate_at(3:5, parse_number) %>% # make numbers actually numbers 
    tbl_df() # for printing 

game_blogs 
#> # A tibble: 119 x 5 
#>  Rank     Blog.Name Facebook.Fans Twitter.Followers Alexa.Rank 
#> <int>      <chr>   <dbl>    <dbl>  <dbl> 
#> 1  1 Kotaku - The Gamer's Guide  997669   1209029  873 
#> 2  2   IGN | Video Games  4070476   4493805  399 
#> 3  3     Xbox Wire  23141452   10210993  879 
#> 4  4 Official PlayStation Blog  38019811   12059607  500 
#> 5  5    Nintendo Life   35977    95044  17727 
#> 6  6    Game Informer  603681   1770812  10057 
#> 7  7   Reddit | Gamers  1003705   430017   25 
#> 8  8     Polygon  623808   485827  1594 
#> 9  9 Xbox Live's Major Nelson   65905   993481  23114 
#> 10 10      VG247  397798   202084  3960 
#> # ... with 109 more rows 

Il est bon de vérifier que tout est analysé comme vous voulez, mais il devrait être utilisable à ce stade.

+0

Cela semble vraiment cool, mais je suis incapable de reproduire vos résultats. Erreur: 'game_blogs <- h %>% html_node ('table')%>% # select noeud Table d'enceinte html_table()%>% de table tournante # dans data.frame set_names (make.names) erreur:' 'x' et nm' doit être de la même longueur' – user2205916

+0

Ah! Désolé, cela utilise la version de développement de 'purrr :: set_names', qui peut prendre une fonction. Vous pouvez l'installer depuis [Github] (https://github.com/tidyverse/purrr/), ou simplement utiliser 'set_names (make.names (noms (.)))' Qui feront la même chose. – alistaire