网页抓取时替换缺失值(rvest)

时间:2017-03-26 23:03:48

标签: r dataframe rvest

我正在尝试编写一个脚本,该脚本将通过Transfermarkt网站提供的播放器列表并收集有关它们的一些信息。为此,我创建了下面的脚本,但遇到了list中29个玩家中的1个的问题。由于一个页面的排列方式与其他页面不同,因此代码仅输出28个播放器的列表,因为它无法在上述页面上找到信息。

我理解为什么我编写的代码在给定页面上找不到任何信息,因此给我一个28的列表,但我不知道如何按顺序重写代码实现我想要的: 脚本只需用" - "替换条目如果它没有找到任何东西,在这种情况下是国籍,对于特定页面上的节点并返回一个包含29个玩家的完整列表,其中包含所有其他信息。

有问题的播放器页面为this,而其他页面的国籍代码中使用了节点,此处为" .dataValue span"。

我对R来说仍然很新,这可能是一个简单的解决方法,但我无法弄明白。任何帮助或建议表示赞赏。

URL <- "http://www.transfermarkt.de/fc-bayern-munchen/leistungsdaten/verein/27/reldata/%262016/plus/1"
WS <- read_html(URL)

Team <- WS %>% html_nodes(".spielprofil_tooltip") %>% html_attr("href") %>% as.character()
Team <- paste0("http://www.transfermarkt.de",Team)

Catcher <- data.frame(Name=character(),Nat=character(),Vertrag=character())

for (i in Team) {
   WS1 <- read_html(i)
   Name <- WS1 %>% html_nodes("h1") %>% html_text() %>% as.character()
   Nat <- WS1 %>% html_nodes(".hide-for-small+ p .dataValue span") %>% html_text() %>% as.character()
   Vertrag <- WS1 %>% html_nodes(".dataValue:nth-child(9)") %>% html_text() %>% as.character()

   if (length(Nat) > 0) {
   temp <- data.frame(Name,Nat,Vertrag)
   Catcher <- rbind(Catcher,temp)
   }
   else {}

cat("*")
}

num_Rows <- nrow(Catcher)
odd_indexes <- seq(1,num_Rows,2)
Catcher <- data.frame(Catcher[odd_indexes,])

1 个答案:

答案 0 :(得分:2)

实际上,如果事情四处移动,真的很容易刮掉整张桌子。我发现purrrrvest的有用补充,允许您迭代URL和节点列表,并轻松将结果强制转换为data.frames:

library(rvest)
library(purrr)

# build dynamically if you like
urls <- c(boateng = 'http://www.transfermarkt.de/jerome-boateng/profil/spieler/26485',
          friedl = 'http://www.transfermarkt.de/marco-friedl/profil/spieler/156990')

# scrape once, parse iteratively
html <- urls %>% map(read_html) 

df <- html %>% 
    map(html_nodes, '.dataDaten p') %>% 
    map_df(map_df, 
           ~list(
               variable = .x %>% html_node('.dataItem') %>% html_text(trim = TRUE), 
               value = .x %>% html_node('.dataValue') %>% html_text(trim = TRUE) %>% gsub('\\s+', ' ', .)
           ), 
           .id = 'player')

df
#> # A tibble: 17 × 3
#>     player              variable              value
#>      <chr>                 <chr>              <chr>
#> 1  boateng           Geb./Alter:    03.09.1988 (28)
#> 2  boateng           Geburtsort:             Berlin
#> 3  boateng         Nationalität:        Deutschland
#> 4  boateng                Größe:             1,92 m
#> 5  boateng             Position:   Innenverteidiger
#> 6  boateng          Vertrag bis:         30.06.2021
#> 7  boateng              Berater:         SAM SPORTS
#> 8  boateng      Nationalspieler:        Deutschland
#> 9  boateng    Länderspiele/Tore:               67/1
#> 10  friedl           Geb./Alter:    16.03.1998 (19)
#> 11  friedl         Nationalität:         Österreich
#> 12  friedl                Größe:             1,87 m
#> 13  friedl             Position: Linker Verteidiger
#> 14  friedl          Vertrag bis:         30.06.2021
#> 15  friedl              Berater:              acta7
#> 16  friedl Akt. Nationalspieler:     Österreich U19
#> 17  friedl    Länderspiele/Tore:                6/0

或者,这些特定的数据位于这些页面的三个位置,因此如果一个不一致,那么其他数据就更好了。或者从整个团队中获取它们 - 不打印国家/地区,但它们位于标记图像的title属性中,可以使用html_attr抓取:

html <- read_html('http://www.transfermarkt.de/fc-bayern-munchen/leistungsdaten/verein/27/reldata/%262016/plus/1')

team <- html %>% 
    html_nodes('tr.odd, tr.even') %>% 
    map_df(~list(player = .x %>% html_node('a.spielprofil_tooltip') %>% html_text(), 
                 nationality = .x %>% html_nodes('img.flaggenrahmen') %>% html_attr('title') %>% toString()))

team
#> # A tibble: 29 × 2
#>            player            nationality
#>             <chr>                  <chr>
#> 1    Manuel Neuer            Deutschland
#> 2    Sven Ulreich            Deutschland
#> 3      Tom Starke            Deutschland
#> 4  Jérôme Boateng            Deutschland
#> 5     David Alaba             Österreich
#> 6    Mats Hummels            Deutschland
#> 7   Javi Martínez                Spanien
#> 8     Juan Bernat                Spanien
#> 9    Philipp Lahm            Deutschland
#> 10        Rafinha Brasilien, Deutschland
#> # ... with 19 more rows