使用R访问API

时间:2017-07-19 09:06:00

标签: r api web-scraping

我正在尝试从API检索信息,该API通过API从条形码中提供产品名称。

我正在使用httr::GET()

API所需的URL包含条形码本身,但我不知道如何自动化系统,以便它可以读取每个条目中包含的条形码,并将其插入到URL中,而无需我复制并手动粘贴代码脚本。

one_code <- GET("api.upcdatabase.org/json/aebfed7a26f24a05efd7f77‌​749dc2fcc/…") 
result <- content(one_code)
result$description

2 个答案:

答案 0 :(得分:2)

需要考虑的其他事项。

首先,该网站为API提供了https,因此您应该使用它,因为您在其他方式提出请求的网络上公开了您的API密钥。

测试核心HTTP状态代码并停止主要HTTP错误(而不是API错误)。

您还应该将API密钥放在类似于环境变量的内容中,以便它永远不会在脚本或GitHub repo提交中结束。使用~/.Renviron(为UPCDATABASE_API_KEY=your_key创建单行条目,然后重新启动R)。

您应该处理错误和成功条件,并考虑返回一个数据框,以便您可以以一种整洁,可访问的方式拥有所有字段。

最后,在返回值之前进行一些基本类型转换,以使返回字段值更易于使用。

library(httr)
library(jsonlite)
library(purrr)

get_upc_code_info <- function(code, api_key=Sys.getenv("UPCDATABASE_API_KEY")) {

   URL <- sprintf("https://api.upcdatabase.org/json/%s/%s", api_key, code)

   res <- GET(URL)

   stop_for_status(res)

   res <- content(res, as="text", encoding="UTF-8")
   res <- fromJSON(res, flatten=TRUE)

   if (res$valid == "true") {

     res <- flatten_df(res)

     res$valid <- TRUE
     res$avg_price <- as.numeric(res$avg_price)
     res$rate_up <- as.numeric(res$rate_up)
     res$rate_down <- as.numeric(res$rate_down)

     return(res)

   } else {

     message(res$reason)
     return(data.frame(number = code, valid = FALSE, stringsAsFactors=FALSE))

   }

}

xdf <- get_upc_code_info("0111222333446")

dplyr::glimpse(xdf)
## Observations: 1
## Variables: 8
## $ valid       <lgl> TRUE
## $ number      <chr> "0111222333446"
## $ itemname    <chr> "UPC Database Testing Code"
## $ alias       <chr> "Testing Code"
## $ description <chr> "http://upcdatabase.org/code/0111222333446"
## $ avg_price   <dbl> 123.45
## $ rate_up     <dbl> 14
## $ rate_down   <dbl> 3

与Aurèle建议的类似,您可以使用该功能更轻松地获取多个代码。由于此函数返回数据框,因此您可以使用purrr::map_df()从单个查找中轻松获得更大,更完整的数据框:

codes <- c("0057000006976", "3228881010711", "0817346023170", "44xx4444444")

xdf <- map_df(codes, get_upc_code_info)

dplyr::glimpse(xdf)
## Observations: 4
## Variables: 8
## $ valid       <lgl> TRUE, TRUE, TRUE, FALSE
## $ number      <chr> "0057000006976", "3228881010711", "0817346023170",...
## $ itemname    <chr> "Heinz Original Beans (Pork &amp; Molasses)", "Lip...
## $ alias       <chr> "", "", "", NA
## $ description <chr> "", "Boîte de 20 sachets", "", NA
## $ avg_price   <dbl> NA, NA, 39.99, NA
## $ rate_up     <dbl> 0, 0, 1, NA
## $ rate_down   <dbl> 0, 0, 0, NA

考虑对此进行最后润色,向API添加POST函数,可能会创建一个Shiny应用程序,以便人们可以通过R提交新条目并将其转换为包。如果你这样做,你甚至可以在网站上获得额外的免费积分。

答案 1 :(得分:0)

将条形码存储在一个数据结构(列表或向量)中:

barcodes <- c(
  "aebfed7a26f24a05efd7f77749dc2fcc",
  "xyz1234567f24a05efd7f77749dc2fcc",
  "pqr9876543f24a05efd7f77749dc2fcc"
)

写一个函数:

scrape <- function(barcode) {
  sample=GET(paste0("api.upcdatabase.org/json/", barcode, "/rest/of/the/url")) 
  result=content(sample)
  result$description
}

并申请:

res <- lapply(barcodes, scrape)

结果存储在一个列表中,因此它们更容易操作。