【问题标题】:Scraping with nested for loops exhibits weird behavior in R使用嵌套 for 循环进行抓取在 R 中表现出奇怪的行为
【发布时间】:2019-04-18 03:04:19
【问题描述】:

我正在尝试抓取 2000-20012001-20022002-2003 季节的曲棍球数据,其中每个季节都包含分布在许多页面上的表格。这是我的抓取功能(ushl_scrape):

ushl_scrape <- function(season, page) {

  # Set url of webpage
  custom_url <- paste0("https://www.eliteprospects.com/league/ushl/stats/", season, "?sort=ppg&page=", page)

  # Scrape
  url <- read_html(custom_url)

  ushl <- url %>% 
    html_node(xpath = "/html/body/section[2]/div/div[1]/div[4]/div[3]/div[1]/div/div[4]/table") %>% 
    html_table() %>% 
    filter(Player != "") %>% 
    mutate(season = season)

  # Return table
  ushl
}

然后我使用这个 for 循环在 3 个不同的季节运行 ushl_scrape。为了解释这个 for 循环,因为我不知道每个季节分布了多少页数据,所以我在 1:10 的页面上抓取数据,一旦我找到一个有 0 行的页面,我就会转到下一年

# Total years
total_years <- paste0(2000:2002, "-", 2001:2003)

# Page
page_num <- c(1:10)

final_list <- vector("list", length = length(total_years))
by_year <- vector("list")


for (ii in seq_along(total_years)) {

  # Sleep for 2 seconds to not bombard server
  Sys.sleep(2)

  for (jj in seq_along(page_num)) {

    Sys.sleep(2)

    # Scrape season[ii] and page_num[jj]
    scraped_table <- ushl_scrape(season = total_years[ii], page = page_num[jj])

    # If scraped table has no rows, exit for loop!
    if (nrow(scraped_table) == 0) {
      break
    } else{
      by_year[[jj]] <- scraped_table
    }
  }

  # Store final_df inside final_list
  final_df <- bind_rows(by_year)
  final_list[[ii]] <- final_df

}

# Finally, bind rows all the elements in list
scraped_df <- bind_rows(final_list)

scraped_df 中,我看到所有三个赛季的数据,但最后,我看到重复的2001-2002 赛季数据添加...

  1. 为什么我的 for 循环最后添加了 2001-2002 赛季的数据?
  2. 我该如何解决?

【问题讨论】:

    标签: r rvest


    【解决方案1】:

    是的,有些行重复了。按原样运行代码会产生 46 个重复行。

    sum(duplicated(scraped_df))
    #[1] 46
    

    问题是您必须为外部 for 循环中的每个 total_year 初始化 by_year。由于您没有这样做,因此它没有清除上一次迭代中的 by_year 值,因此没有清除重复项。

    for (ii in seq_along(total_years)) {
    
      # Sleep for 2 seconds to not bombard server
      Sys.sleep(2)
      by_year <- vector("list") # <- Added this line
      for (jj in seq_along(page_num)) {    
          Sys.sleep(2)
    
         # Scrape season[ii] and page_num[jj]
         scraped_table <- ushl_scrape(season = total_years[ii], page = page_num[jj])
          #browser()
         # If scraped table has no rows, exit for loop!
         if (nrow(scraped_table) == 0) {
            break
         } else{
             by_year[[jj]] <- scraped_table
         }
       }
    
     # Store final_df inside final_list
     final_df <- bind_rows(by_year)
     final_list[[ii]] <- final_df
    
    }
    
    scraped_df <- bind_rows(final_list)
    

    我们现在可以检查重复行了

    sum(duplicated(scraped_df))
    #[1] 0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-24
      • 2018-01-21
      • 2019-02-11
      • 1970-01-01
      相关资源
      最近更新 更多