2

我正在尝试使用 github API 获取有关存储库的信息。我为此使用 R。一些 url 抛出 403 错误。不幸的是,这会停止我的功能并破坏 fromJSON 功能。再次调用 fromJSON 总是会导致“client error: (403) Forbidden”

有没有办法处理 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)
}
4

3 回答 3

4

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

  • 使用内置的 JSON->R 解码,httr免费为您提供
  • 检查有效的响应代码
  • 说明返回值中可能缺少的字段
  • 用于data.table数据框架构建的效率和更容易处理

它还免费为您提供进度条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_statusvs更改它warn_for_status或只是测试并自行停止)。这样你会得到不正确NA的 s 。

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

于 2015-06-27T11:44:08.837 回答
1

有关异常处理的指南,请参阅 ?try 和 ?tryCatch。

这是一个 POC,它显示了如何使 404 错误fromJSON继续,继续打印“ok”:

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

您可以测试 return fromtry以查看代码是否引发错误。有关更多信息,请参阅帮助页面。

于 2015-06-26T19:53:54.980 回答
1

这是使用 httr 处理请求的更好方法。它还将 plyr 用于主循环。无效条目中包含 NA。如果需要,您可以稍后删除它们。

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
  })
}
于 2015-06-26T20:18:17.493 回答