Как загрузить и / или извлечь данные, хранящиеся в «сыром» двоичном zip-объекте внутри объекта ответа в R? - PullRequest
0 голосов
/ 21 октября 2019

Я не могу загрузить или прочитать zip-файл из запроса API с использованием пакета httr. Могу ли я попробовать другой пакет, который позволит мне загружать / читать двоичные zip-файлы, хранящиеся в ответе на запрос get в R?

Я пробовал двумя способами:

  1. использовал GET для получения объекта ответа типа application / json (успешно), а затем использовал fromJSON для извлечения контента с использованием контента (my_response, 'text'). Вывод содержит столбец с именем «zip», который представляет собой данные, которые я заинтересован в загрузке, и в документации указано, что это двоичный файл в кодировке base64. Этот столбец в настоящее время представляет собой действительно длинную строку случайных букв, и я не уверен, как преобразовать это в фактический набор данных.

  2. Я попытался обойти использование fromJSON, потому что заметил полекласса 'raw' внутри самого объекта ответа. Этот объект представляет собой список случайных чисел, которые, как я подозреваю, являются двоичным представлением набора данных. Я попытался использовать rawToChar (my_response $ content), чтобы попытаться преобразовать необработанный тип данных в символ, но в результате получается та же длинная символьная строка, что и в # 1.

  3. Я заметил, что с подходом# 1, если я использую base64_dec (), чтобы попытаться преобразовать длинную символьную строку, я также получаю тот же тип вывода, что и поле 'raw' в самом объекте ответа.
getzip1  <- GET(getzip1_link)
getzip1 # successful response, status 200
df <- fromJSON(content(getzip1, "text"))

df$status # "OK"
df$dataset$zip # <- this is the very long string of letters (eg. "I1NC5qc29uUEsBAhQDFA...")

# Method 1: try to convert from the 'zip' object in the output of fromJSON
try1 <- base64_dec(df$dataset$zip)
#looks similar to getzip1$content (i.e.  this produces the list of numbers/letters 50 4b 03 04 14 00, etc, perhaps binary representation)

# Method 2: try to get data directly from raw object
class(getzip1$content) # <- 'raw' class object directly from GET request
try2 <- rawToChar(getzip1$content) #returns same output as df$data$zip


Iдолжен иметь возможность использовать либо необработанный объект 'content' из моего ответа, либо длинную символьную строку в объекте 'zip' выходных данных fromJSON, чтобы просмотреть набор данных или каким-либо образом загрузить его. Я не знаю, как это сделать. Пожалуйста, помогите!

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Добро пожаловать!

На основе документации для API ответ на конечную точку getDataset имеет схему

Архив набора данных, включая метаинформацию,Сам набор данных закодирован в base64, чтобы разрешить двоичные передачи ZIP.

{
 "status": "OK",
 "dataset": {
 "state_id": 5,
 "session_id": 1624,
 "session_name": "2019-2020 Regular Session",
 "dataset_hash": "1c7d77fe298a4d30ad763733ab2f8c84",
 "dataset_date": "2018-12-23",
 "dataset_size": 317775,
 "mime": "application\/zip",
 "zip": "MIME 64 Encoded Document"
 }
}

Мы можем использовать R для получения данных с помощью следующего кода:

library(httr)
library(jsonlite)
library(stringr)
library(maditr)
token <- "" # Your API key
session_id <- 1253L # Obtained from the getDatasetList endpoint
access_key <- "2qAtLbkQiJed9Z0FxyRblu" # Obtained from the getDatasetList endpoint
destfile <- file.path("path", "to", "file.zip") # Modify
response <- str_c("https://api.legiscan.com/?key=",
                  token,
                  "&op=getDataset&id=",
                  session_id,
                  "&access_key=",
                  access_key) %>%
  GET()
status_code(x = response) == 200 # Good
body <- content(x = response,
                as = "text",
                encoding = "utf8") %>%
  fromJSON() # This contains some extra metadata
content(x = response,
        as = "text",
        encoding = "utf8") %>%
  fromJSON() %>%
  getElement(name = "dataset") %>%
  getElement(name = "zip") %>%
  base64_dec() %>%
  writeBin(con = destfile)
unzip(zipfile = destfile)

unzip будетраспакуйте файлы, которые в этом случае будут выглядеть как

hash.md5 # Can be checked against the metadata
AL/2016-2016_1st_Special_Session/bill/*.json
AL/2016-2016_1st_Special_Session/people/*.json
AL/2016-2016_1st_Special_Session/vote/*.json

Как всегда, оберните ваш код в функции и прибыль.

PS: Вот как код должен выглядеть в Джулии каксравнение.

using Base64, HTTP, JSON3, CodecZlib
token = "" # Your API key
session_id = 1253 # Obtained from the getDatasetList endpoint
access_key = "2qAtLbkQiJed9Z0FxyRblu" # Obtained from the getDatasetList endpoint
destfile = joinpath("path", "to", "file.zip") # Modify
response = string("https://api.legiscan.com/?",
                  join(["key=$token",
                        "op=getDataset",
                        "id=$session_id",
                        "access_key=$access_key"],
                        "&")) |>
    HTTP.get
@assert response.status == 200
JSON3.read(response.body) |>
    (content -> content.dataset.zip) |>
    base64decode |>
    (data -> write(destfile, data))
run(pipeline(`unzip`, destfile))
0 голосов
/ 21 октября 2019

Просмотрите этот ответ о том, как открыть ZIP-файл, загруженный с URL-адреса


Получение ZIP-файла с помощью httr

...