【问题标题】:Replacing missing value when web scraping (rvest)网页抓取时替换缺失值(rvest)
【发布时间】:2017-08-19 12:32:38
【问题描述】:

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

我理解为什么我编写的代码在给定页面上找不到任何信息,因此给了我 28 个列表,但我不知道如何重写代码以实现我想要的: 如果脚本没有找到任何内容(在本例中为国籍),则脚本只需将条目替换为“-”,用于特定页面上的节点,并返回包含 29 名玩家的完整列表,其中包含所有其他信息。

有问题的玩家页面是this,而其他页面有代码中用于国籍的节点,这里是“.dataValue span”。

我对 R 还是很陌生,这可能很容易解决,但 atm 我无法弄清楚。感谢您提供任何帮助或建议。

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,])

【问题讨论】:

    标签: r dataframe rvest


    【解决方案1】:

    老实说,刮掉整张桌子更容易,以防万一事情发生变化。我发现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
    

    【讨论】:

    • 感谢您的建议!我肯定会很快研究 Purrr,但现在我只是用“if”语句做了一个简单的修复。
    • 至少尝试使用lapplypurrr::map 的基本等效项)而不是for 循环;你会发现它是一种更有用的结构,在 R 中随处可见。
    猜你喜欢
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 2020-07-18
    • 2019-02-17
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多