R 从 API 抓取 JSON 数据

问题描述 投票:0回答:1

我正在尝试从相对较新的 nypdonline.org 网站获取各种警方统计数据的公共数据,该网站可以通过多种方式访问。通常查询此数据的主要方法是通过位于 https://nypdonline.org/link/2 的在线查找工具,或直接使用唯一的税号,例如:http://oip .nypdonline.org/view/1/@TAXID=938661.

理想情况下,我希望 R 脚本能够遍历税号列表(这是唯一标识符),以从网站中提取特定数据点 - 我目前正在查看“总逮捕数”,因为这将有助于充当控制在回归工作中,但如果我可以获得一个数据点,我应该能够获得所有数据点。

主要问题是该网站经历了查询第二个 URL 的过程,我认为它从中提取 JSON 数据。我的第一个努力是尝试使用 RVest 定位单个页面,并使用 html_nodes() 尝试选择 CSS 元素或 XPath 元素:

library(rvest)
library(dplyr)
url <- "http://oip.nypdonline.org/view/1/@TAXID=938661"
webpage <- read_html(url)
total_arrests <- webpage %>%  
html_nodes("[various CSS / xpath elements attempted here]") %>% 
  html_text() %>%
  as.numeric()

但这不会产生任何结果;检查 HTML,我可以看到嵌入的这些数字(参见图片一和代码中的数字 201),但我找不到实际数据抓取它们的方法,大概是因为此代码的排列方式它们的位置动态变化,或者因为部分他们的数据是一个随机标识符。

使用 Chrome 中的开发工具,我可以看到(图 2)该网站正在向辅助 URL 发送请求。我认为这是我真正需要查询 JSON 数据的 URL。

我的困惑可能只是具体如何执行此操作,特别是在一个似乎从 MSSQL 数据库查询 JSON 数据的网站的情况下 - 如果我直接访问以下网站,我可以看到似乎是 JSON 参数,包括我需要的唯一税号值的可能变量: http://oip.nypdonline.org/api/reports/

但这看起来只是数据的框架,我需要一个我找不到也不太明白的步骤来实际查询 API 来获取特定数据。我可以轻松地将上述 JSON 页面数据抓取到 R 中,但最终我得到的基本上是 JSON 框架,没有任何实际数据:

library(rvest)
library(jsonlite)
url <- "http://oip.nypdonline.org/api/reports/"
webpage <- read_html(url)
json_data <- html_text(html_nodes(webpage, "body"))
data_list <- fromJSON(json_data, flatten = TRUE)
View(data_list)

这对我提供了 JSON 类别非常有帮助,在其中我想要搜索的唯一税号 ID 值(也在上面的图像 3 JSON 中突出显示)可能类似于:

json[[1]][["DataSource"]][["Parameters"]][[1]][["Name"]]

但我不太清楚如何使用它来实际查询 API。很高兴能转向正确的方向,因为我认为有一个元素我只是不理解。

r json
1个回答
0
投票

从 Google Chrome 开发者控制台,我发现了一个包含以下内容的 POST 网址

url <- "https://oip.nypdonline.org/api/reports/1/datasource/list"
payload <- '{filters: [{key: "@TAXID", label: "TAXID", values: ["938661"]}]}'

我使用了

httr::POST()
,然后使用 listviewer 包查看结果

response <- httr::POST(url, content_type("application/json"), body = payload)
json <- httr::content(response, as = "text")
listviewer::jsonedit(json)

可以使用

jsonlite::fromJSON()
将其提取为 R 对象,但我使用 CRAN 包 rjsoncons 将所有内容提取到 data.frame (tibble)

> rjsoncons::j_pivot(json, as = "tibble")
# A tibble: 1 × 6
  Label                   ImageURL CodeTemplate Items  Interactions RelatedItems
  <chr>                   <chr>    <chr>        <list> <list>       <list>      
1 "HERNANDEZ, GREGORY D … https:/… "HERNANDEZ,… <list> <list [0]>   <list [0]>  

或者只是使用 JMESpath

的一部分
> rjsoncons::j_pivot(json, "[0].Items", as = "tibble")
# A tibble: 6 × 9
  Id                Label Value CodeTemplate LabelAlignment LabelFont LabelColor
  <chr>             <chr> <chr> <chr>        <chr>          <chr>     <list>    
1 a2fded09-5439-4b… Rank: "POL… {Value}      text-right     12px Ari… <chr [1]> 
2 20e891ce-1dcf-4d… Appo… "7/1… {Value}      text-right     12px Ari… <NULL>    
3 1692f3bf-ed70-4b… Comm… "049… {Value}      text-right     12px Ari… <chr [1]> 
4 8a2bcb6f-e064-44… Assi… "7/5… {Value}      text-right     12px Ari… <NULL>    
5 0ec90f94-b636-47… Ethn… "HIS… {Value}      text-right     12px Ari… <chr [1]> 
6 42f74dfc-ee54-4b… Shie… "264… {Value}      text-right     12px Ari… <NULL>    
# ℹ 2 more variables: ValueAlignment <chr>, ValueFont <chr>

也许这会让你在路上走得更远?

© www.soinside.com 2019 - 2024. All rights reserved.