es api获取数据
有很多很棒的R软件包 ,可让您使用一个函数从API导入数据。 但是,有时API没有已编写的函数。 好消息是,编写自己的代码很容易。
我将使用AccuWeather API对此进行演示,但是该过程和代码将适用于大多数其他使用密钥进行身份验证的API。
注册以访问API
如果您想继续,请访问developer.accuweather.com并注册一个免费帐户。 在“软件包和定价”下,选择“限制试用”,该限制每天允许50次API调用-如果您只想每天检查几次本地预测,就足够了,但是对于任何面向公众的应用程序显然都不能满足要求。
如果没有立即为您提供创建应用的选项,请转到“我的应用”并创建一个新应用。
对于使用API的地方,我选择了“其他”,对于正在创建的内容,我选择了“内部应用程序”,对于编程语言,我选择了“其他”。 应该为您的应用分配一个API密钥。
如果您不想将该API密钥硬编码到AccuWeather预测脚本中,请将其保存为R环境变量。 最简单的方法是使用usethis包。 usethis::edit_r_environ()
打开R环境文件进行编辑。 向该文件添加诸如ACCUWEATHER_KEY = 'my_key_string'
的行,保存文件,然后重新启动R会话。 现在,您可以使用Sys.getenv("ACCUWEATHER_KEY")
访问键值,而无需对值本身进行硬编码。
确定API的URL结构
对于这个项目,我将首先加载httr,jsonlite和dplyr软件包:httr用于从API获取数据,jsonlite用于解析它,以及dplyr最终使用管道(您也可以使用magrittr软件包)。
接下来-这很关键- 您需要知道如何构造URL以便从API请求所需的数据 。 弄清查询结构可能是该过程中最困难的部分,具体取决于API的文档编制方式。 幸运的是, AccuWeather API文档非常出色。
任何API查询都需要一个资源URL,或者我认为是URL根的URL,然后是查询的特定部分。 这是AccuWeather在其一日预报API的文档中所说的:
http://dataservice.accuweather.com /forecasts/v1/daily/1day/{locationKey}
预测的基本URL通常是恒定的,但是该URL需要一个位置代码 。 如果您只是在寻找一个位置的天气预报,那么您可以作弊并使用AccuWeather网站在accuweather.com上搜索天气预报,然后检查返回的URL。 当我搜索邮政编码01701(我们位于马萨诸塞州弗雷明汉的办公室)时,以下URL随预测一起返回:
https://www.accuweather.com/en/us/framingham/01701/weather-forecast/571_pc
看到末尾的/571_pc
吗? 那是位置键。 您还可以使用AccuWeather Locations API以编程方式提取位置代码(稍后将显示),或者使用AccuWeather的基于Web的Locations API工具之一,例如City Search或Postal Code 。
构造一个请求URL
特定数据请求的查询参数将附加到基本URL的末尾。 第一个参数以问号开头,后跟名称等于值。 任何其他键/值对都添加一个与号,后跟名称等于值。 因此,要添加我的API密钥,URL如下所示:
http://dataservice.accuweather.com/forecasts/v1/daily/1day/571_pc?apikey=MY_KEY
如果我想添加第二个查询参数(例如,将默认详细信息从false更改为true),则看起来像这样:
http://dataservice.accuweather.com/forecasts/v1/daily/1day/571_pc?apikey=MY_KEY&details=true
获取数据
我们可以使用httr::GET()
函数对该URL发出HTTP GET
请求,例如
my_url <- paste0("http://dataservice.accuweather.com/forecasts/",
"v1/daily/1day/571_pc?apikey=",
Sys.getenv("ACCUWEATHER_KEY"))
my_raw_result <- httr::GET(my_url)
创建URL的paste0()
命令将URL根分成两行以提高可读性,然后添加了存储在ACCUWEATHER_KEY R环境变量中的API密钥。
my_raw_result
是一个有些复杂的列表。 我们想要的实际数据主要是内容,但是如果您看一下它的结构,就会发现它是一种“原始”格式,看起来像二进制数据。
幸运的是,使用httr软件包,可以轻松地使用content()
函数将原始格式转换为可用格式。
解析结果
content()
为您提供三个转换选项:作为原始转换(在这种情况下,绝对没有帮助); 解析后,似乎通常会返回某种列表; 和文字。 对于JSON(尤其是嵌套JSON),我发现文字是最容易使用的文本。 这是代码:
my_content <- httr::content(my_raw_result, as = 'text')
这就是jsonlite包的来源fromJSON()
函数会将JSON文本字符串从content()
转换为更可用的R对象。
以下是运行dplyr的部分结果glimpse()
的函数my_content
拿到一看结构:
这是一个包含两个项目的列表。 第一项包含一些我们可能想要的元数据和一个文本字段。 第二项是一个数据框架,其中包含许多我们肯定要进行预测的数据点。
仅在该数据帧上运行glimpse()
显示它是嵌套的JSON,因为某些列实际上是它们自己的数据帧。 但是fromJSON()
使这一切变得无缝。
Observations: 1
Variables: 8
$ Date <chr> "2019-08-29T07:00:00-04:00"
$ EpochDate <int> 1567076400
$ Temperature <df[,2]> <data.frame[1 x 2]>
$ Day <df[,3]> <data.frame[1 x 3]>
$ Night <df[,3]> <data.frame[1 x 3]>
$ Sources <list> ["AccuWeather"]
因此,这些是从API提取数据的基本步骤:
- 找出API的基本URL和查询参数,并构造一个请求URL。
- 在URL上运行
httr::GET()
。 - 用
content()
解析结果。 您可以使用as = 'parsed'
尝试它,但是如果返回复杂列表,请尝试as = 'text'
。 - 如有必要,请在该解析对象上运行
jsonlite::fromJSON()
。
最后总结一些要点。 首先,如果再次查看my_raw_result
(从GET
返回的初始对象),则应该看到状态码。 200表示一切正常。 但是400年代的密码意味着出了点问题。 如果要编写函数或脚本,则可以在运行其他代码之前检查状态代码是否在200年代。
其次,如果您有多个查询参数,那么使用paste0()
命令将它们全部串在一起可能会有些烦人。 GET()
还有另一个选项,它创建查询参数的命名列表,例如:
my_raw_result2 <- GET(url,
query = list(
apikey = Sys.getenv("ACCUWEATHER_KEY"),
details = 'true'
)
)
看到结构了吗? GET()
函数将基本URL作为第一个参数,并将名称和值的列表作为第二个查询参数。 每个都是name = value
,名称不带引号。 其余代码相同。
这也适用于AccuWeather Locations API 。
以下是该API的要求:
我可以使用与Forecast API类似的代码,但是这次分别使用查询参数apikey
和q
,AccuWeather键和我要搜索的地方的文本:
base_url <- "http://dataservice.accuweather.com/locations/v1/cities/search"
ny_location_raw <- GET(base_url,
query = list(apikey = Sys.getenv("ACCUWEATHER_KEY"),
q = "New York, NY"
))
ny_parsed <- content(ny_location_raw, as = 'text') %>%
fromJSON()
位置代码在“密钥”列中。
> glimpse(ny_parsed)
Observations: 1
Variables: 15
$ Version <int> 1
$ Key <chr> "349727"
$ Type <chr> "City"
$ Rank <int> 15
$ LocalizedName <chr> "New York"
$ EnglishName <chr> "New York"
$ PrimaryPostalCode <chr> "10007"
$ Region <df[,3]> <data.frame[1 x 3]>
$ Country <df[,3]> <data.frame[1 x 3]>
$ AdministrativeArea <df[,7]> <data.frame[1 x 7]>
$ TimeZone <df[,5]> <data.frame[1 x 5]>
$ GeoPosition <df[,3]> <data.frame[1 x 3]>
$ IsAlias <lgl> FALSE
$ SupplementalAdminAreas <list> [<data.frame[1 x 3]>]
现在,您只需要代码即可使用从API提取的数据。
有关R的更多技巧,请访问“使用R进行更多操作”页面,其中包含可搜索的文章和视频表 。
翻译自: https://www.infoworld.com/article/3434627/get-api-data-with-r.html
es api获取数据