2015-06-26 38 views
1

我想要使用github API获取有关存储库的信息。我为此使用了R。某些网址投掷了403个错误。不幸的是,这会停止我的函数并打破fromJSON函数。再次调用fromJSON总是会导致“客户端的错误:(403)禁止”用jsonlite在R上刮网页

是否有处理R中的异常,所以我的功能,可以继续执行,如果我得到一个403

我的功能如下方式:

getData <- function(start, end) { 
    languages = NULL 
    names = NULL 
    base_url <- 'https://api.github.com/users/' 
    for(num in start:end) { 
    url <- print(paste(base_url,num, '/repos', sep='')) 
    df<- fromJSON(url) 
    languages <- c(languages, df$language) 
    names <- c(names, df$name) 
    } 
    r = data.frame(languages, names) 
    return(r) 
} 
+0

你需要这样刮吗? R有一些github api包,包括这一个https://github.com/cscheid/rgithub – hrbrmstr

+0

你的'403 Forbidden'很可能是GitHub API,告诉你你超出了未经过验证的API限制,顺便说一句。 – hrbrmstr

回答

1

请参阅try和tryCatch以获取异常处理指南。

这里有一个POC,显示可制成如何从fromJSON 404错误继续,马上就要打印“OK”:

> try({fromJSON("http://www.google.com/nosuch")}) ; cat("ok\n") 
Error in download_raw(txt) : client error: (404) Not Found 
ok 

您可以测试从try回看如果代码引发的错误。查看更多帮助页面。

1

下面是使用httr处理请求的更好方法。它也使用plyr作为主循环。无效的条目中有NAs。如果需要,可以稍后删除它们。

library("httr"); library("plyr"); library("jsonlite") 
getData <- function(start, end) { 
    base_url <- "https://api.github.com/users/" 
    ldply(start:end, function(num) { 
    cat(url <- paste0(base_url,num, "/repos"), "\n") 
    resp <- GET(url) 
    if (status_code(resp) == 200) { 
     df <- fromJSON(content(resp, "text")) 
     out <- data.frame(language = NA, name = NA) 
     if (length(df) > 0) { 
     out <- df[, c("language", "name")] 
     } 
    } 
    out 
    }) 
} 
2

正如我在我的评论中所建议的那样,您最好使用实现它的R包之一使用GH API。但是,如果你有决心从头开始构建它,下面的代码:

  • 使用内置的JSON-> [R解码功能,httr为您提供免费
  • 检查有效的响应代码
  • 账户可能丢失的字段在返回值
  • 使用data.table的效率和数据帧的建筑更容易处理

它也给你进度条s免费pbapply

library(httr) 
library(data.table) 
library(pbapply) 

get_data <- function(start, end) { 
    base_url <- 'https://api.github.com/users/%d/repos' 
    pblapply(start:end, function(i) { 
    resp <- GET(sprintf(base_url, i)) 
    warn_for_status(resp) 
    if (status_code(resp) == 200) { 
     dat <- content(resp, as="parsed") 
     data.table(name=sapply(dat, function(x) ifelse(is.null(x[["name"]]), NA, x[["name"]])), 
       language=sapply(dat, function(x) ifelse(is.null(x[["language"]]), NA, x[["language"]]))) 
    } else { 
     data.table(language=NA, name=NA) 
    } 
    }) 
} 

gh <- rbindlist(get_data(1, 6)) 

gh 
##      name  language 
## 1: python-youtube-library  Python 
## 2:      t   NA 
## 3:    dotfiles   VimL 
## 4:    pair-box   NA 
## 5:   6.github.com JavaScript 
## 6:    AndAnd.Net   C# 
## 7:   backbone-tunes JavaScript 
## 8:   battletower CoffeeScript 
## 9:    BeastMode   Ruby 
## 10: blurry_search.coffee JavaScript 
## 11:    bootstrap   CSS 
## 12:  browser-deprecator JavaScript 
## 13:   classify.js JavaScript 
## 14:   cocoa-example Objective-C 
## 15:    Colander CoffeeScript 
## 16:  comic_reader.js JavaScript 
## 17:   crawl-tools  Python 
## 18:   CS-Projects  Python 
## 19:    cssfast CoffeeScript 
## 20:    danbooru   Ruby 
## 21:     Dex CoffeeScript 
## 22:    dnode-ruby   Ruby 
## 23:    domain-gen   Ruby 
## 24:   domainatrix   Ruby 
## 25:    Doodler   Java 
## 26:    dotfiles   VimL 
## 27:     dothis   Ruby 
## 28:    elixir-web  Elixir 
## 29:   faster_manga CoffeeScript 
## 30:     favmix   Java 
## 31:     fluent   Ruby 
## 32:  fluid-image-grid JavaScript 
## 33:    freeform   Ruby 
## 34:   FreeYourCode   Ruby 
##      name  language 

让自由API访问变得简单。如果代码得到403,但是会继续处理(您可以用stop_for_statuswarn_for_status或仅仅测试并自行停止)来修改该代码。你会以这种方式不正确的NA

IMO使用经过身份验证的API访问会更加有利。