用R循环遍历url

时间:2018-01-29 01:24:22

标签: r loops web-scraping rvest

我需要从网址下载一系列Excel文件,如下所示:

http://example.com/orResultsED.cfm?MODE=exED&ED=01&EventId=31
http://example.com/orResultsED.cfm?MODE=exED&ED=02&EventId=31
...
http://example.com/orResultsED.cfm?MODE=exED&ED=87&EventId=31

我在循环中有一些构建块,例如:

for(i in 1:87) {
    url <- paste0("http://example.com/orResultsED.cfm?MODE=exED&ED=", i, "&EventId=31")
    file <- paste0("Data/myExcel_", i, ".xlsx")
    if (!file.exists(file)) download.file(url, file) 
}

我的问题

  1. 我需要seq前置0(我试过sprintf没有运气)
  2. 我还想导入Excel文件,跳过前两行并将它们追加到另一行(它们也有相同的列)
  3. 更新

    @akrun解决方案效果很好。但事实证明并非所有的Excel文件都具有相同的列数:

    map(files, ~read.xlsx(.x, 
                             colNames = FALSE,
                             sheet = 1, 
                             startRow = 4,
                             )) %>%
      bind_rows
    
    Error in bind_rows_(x, .id) : 
      Column `X1` can't be converted from numeric to character
    

    我认为这个错误实际上指向了不相等的列数。我尝试添加fill = NA(在测试map_df()时),但它没有帮助。

3 个答案:

答案 0 :(得分:4)

我们可以使用sprintf

创建它
paste0("http://example.com/orResultsED.cfm?MODE=exED&ED=", sprintf("%02d", 1), "&EventId=31")
#[1] "http://example.com/orResultsED.cfm?MODE=exED&ED=01&EventId=31"

在循环中,

for(i in 1:87) {
  i1 <- sprintf('%02d', i)
   url <- paste0("http://example.com/orResultsED.cfm?MODE=exED&ED=", i1, "&EventId=31")
   file <- paste0("Data/myExcel_", i, ".xlsx")
   if (!file.exists(file)) download.file(url, file) 
}

假设文件已下载到工作目录

files <- list.files(full.names = TRUE)
library(openxlsx)
library(purrr)
library(dplyr)
map(files, ~read.xlsx(.x, sheet = 1, startRow = 3))  %>%
      bind_rows

或者正如评论中提到的@hrbrmstr,可以使用map_df返回单个数据集

map_df(files, ~read.xlsx(.x, sheet = 1, startRow = 3))

更新

根据OP的评论,某些数据集的列类似乎有所不同。在这种情况下,bind_rows会出错。一种选择是使用rbindlist

中的data.table
map(files, ~read.xlsx(.x, sheet = 1, startRow = 3))  %>%
      data.table::rbindlist(fill = TRUE)

答案 1 :(得分:3)

下载和阅读1循环。希望如果不使用plyr::rbind.fill而不是do.call(rbind, list)

之类的列,则会对齐列
do.call(rbind, lapply(1:87, function(n) {
    url <- paste0("http://example.com/orResultsED.cfm?MODE=exED&ED=", 
        sprintf("%02d", n), "&EventId=31")
    file <- paste0("Data/myExcel_", n, ".xlsx")
    if (!file.exists(file)) download.file(url, file) 
    readxl::read_excel(file, skip=2)
    Sys.sleep(5)
}))

答案 2 :(得分:2)

您也可以使用regmatches

 num=sprintf("%02.0f",1:87)
 urls=rep("http://example.com/orResultsED.cfm?MODE=exED&ED=01&EventId=31",87)
`regmatches`(urls,regexpr("\\d+",urls))<-num
 urls[87]
[1] "http://example.com/orResultsED.cfm?MODE=exED&ED=87&EventId=31"

拥有所有文件:

 files <- paste0("Data/myExcel_",num , ".xlsx")

下载文件:

  mapply(function(x,y)if(!file.exists(x))download.file(y,x),files,urls)