2016-08-01 81 views
0

我正在从在线API加载数据。数据分页,因此我需要连续拨打电话。无法用foreach()使用并行化调用休息api

因此,我设置了一个最终rbind()输出的并行foreach()循环。

下面的代码:

library('foreach') 
    library('parallel') 
    library('jsonlite') 

    registerDoMC(cores = parallel::detectCores()) 

    data <- foreach(page = 1:10, .combine = rbind) %dopar% { 

     raw.data <- fromJSON(paste(endpoint, '&page=', page, sep ='')) 

     raw.data <- raw.data$results 

     data.piece <- raw.data[c('id', 'scraper', 'title', 'text', 'ts', 'url', 'pertinence', 'source')] 

     data.piece 
    } 

端点是一个REST URL。

循环返回NULL,并且它立即运行(每次调用确实需要几秒钟)。

因此看起来呼叫被跳过。如果我不是并行运行相同的代码,它可以毫无问题地工作。

+0

您应该在上面的代码块之前包含您设置并行后端的代码,以及使这个示例可重现的所有其他内容('endpoint','page'等)。 – nrussell

+0

页面已在代码中定义。我添加了使用过的库。 正如我所说的端点是一个休息网址(我不能透露),但任何休息网址都可以;正如我所说的并行运行代码(%do%而不是%dopar%),完美地工作,所以端点不是问题。 – Bakaburg

+0

如果有任何网址,那么可以使用任何可以重现错误的网址来举例说明。 – nrussell

回答

1

我碰到了类似的情况,适应我的代码到你的情况产生以下:

library(jsonlite) 
library(dplyr) 
library(foreach) 
library(doParallel) 

fetch.data <- function(page) { 
    # confirm the url you are fetching data from ... 
    url = 'http://api.paginated/?page=' 
    endpoint = paste0(url, page) 
    print(paste0('fetching data for => ', endpoint)) 
    raw.data <- fromJSON(endpoint, flatten = TRUE) 
    raw.data 
} 


no_cores <- detectCores() 
cluster <- makeCluster(no_cores) 
registerDoParallel(cluster) 
t.start <- Sys.time() 
data <- foreach(page=1:10, .combine=bind_rows, .packages=c('jsonlite')) %dopar% { 
    if (page %% 4 == 0) Sys.sleep(1) 
    page_data <- fetch.data(page) 
    page_data <- page_data$results 
    data.piece <- page_data[c('id', 'scraper', 'title', 'text', 'ts', 'url', 'pertinence', 'source')] 
    data.piece 
} 
t.end <- Sys.time() 
stopImplicitCluster() 
print(t.end - t.start) 

此代码最近为我工作。唯一需要注意的是你在api的限制范围内进行游戏。这可能意味着你必须减慢你的脚本 - 例如,每4页等待1秒。

+0

这是使它工作的一块? – Bakaburg