Запрос httr POST к API возвращает ошибку 400

Я работаю с пакетом httr в R, пытаясь запросить API postcode.io (http://postcodes.io/docs).

Я могу успешно запросить один почтовый индекс в соответствии с инструкциями, используя: sample4 <- GET("api.postcodes.io/postcodes/EN14RF")

Когда я пытаюсь запросить несколько почтовых индексов, я немного теряюсь. Инструкции postcode.io предлагают

POST https://api.postcodes.io/postcodes?q=[postcode]

где указан объект JSON, содержащий массив почтовых индексов. У меня есть вектор R, содержащий почтовые индексы, которые я пытался преобразовать в объект JSON как таковой с помощью:

a <- toJSON(a)

где мой вектор R 'a':

structure(c(4L, 5L, 3L, 6L, 1L, 2L), .Label = c("Bn14 9aw", "CR0 4BE", "E5 8HB", "EN1 4RF", "G42 8QN", "SA1 3UL"), class = "factor")

Теперь, когда я пытаюсь запросить API со следующей строкой кода:

sample4 <- POST("https://api.postcodes.io/postcodes?q=[postcode]", body = list(postcode = add1JSON))

Я получаю сообщение об ошибке: "Invalid JSON submitted. You need to submit a JSON object with an array of postcodes or geolocation objects"

У меня такое ощущение, что это потому, что я предоставляю не массив, а безымянный список, например. мой объект JSON должен выглядеть так:

{"postcodes":"[ \"EN14RF\", \"G428QN\", \"E58HB\", \"SA13UL\", \"Bn149aw\", \"CR04BE\" ]"}

Не это: "[ \"EN14RF\", \"G428QN\", \"E58HB\", \"SA13UL\", \"Bn149aw\", \"CR04BE\" ]"

Кто-нибудь может мне с этим помочь? У меня есть ощущение, что это как-то связано с моим вызовом toJSON, но я не смог найти аналогичный пример на форуме или на странице разработчиков API :(

Большое спасибо

Марти


person marty_c    schedule 01.08.2016    source источник


Ответы (3)


У них очень плохо написана документация по API. Кажется, это цель этого конкретного вызова API:

library(httr)
library(jsonlite)
library(dplyr)

post_codes <- c("Bn14 9aw", "CR0 4BE", "E5 8HB", "EN1 4RF", "G42 8QN", "SA1 3UL")

res <- POST("https://api.postcodes.io/postcodes",
            body=list(postcodes=post_codes),
            encode="json")


status_code(res)
## [1] 200

content(res, as="text") %>%
  fromJSON(flatten=TRUE) %>%
  glimpse()
## List of 2
##  $ status: int 200
##  $ result:'data.frame':  6 obs. of  29 variables:
##   ..$ query                            : chr [1:6] "Bn14 9aw" "E5 8HB" "CR0 4BE" "EN1 4RF" ...
##   ..$ result.postcode                  : chr [1:6] "BN14 9AW" "E5 8HB" "CR0 4BE" "EN1 4RF" ...
##   ..$ result.quality                   : int [1:6] 1 1 1 1 1 1
##   ..$ result.eastings                  : int [1:6] 514948 534934 531978 534957 264583 258092
##   ..$ result.northings                 : int [1:6] 104386 185332 164963 199610 192273 662417
##   ..$ result.country                   : chr [1:6] "England" "England" "England" "England" ...
##   ..$ result.nhs_ha                    : chr [1:6] "South East Coast" "London" "London" "London" ...
##   ..$ result.longitude                 : num [1:6] -0.3693 -0.0553 -0.1055 -0.0494 -3.9572 ...
##   ..$ result.latitude                  : num [1:6] 50.8 51.6 51.4 51.7 51.6 ...
##   ..$ result.parliamentary_constituency: chr [1:6] "East Worthing and Shoreham" "Hackney South and Shoreditch" "Croydon South" "Enfield North" ...
##   ..$ result.european_electoral_region : chr [1:6] "South East" "London" "London" "London" ...
##   ..$ result.primary_care_trust        : chr [1:6] "West Sussex" "City and Hackney Teaching" "Croydon" "Enfield" ...
##   ..$ result.region                    : chr [1:6] "South East" "London" "London" "London" ...
##   ..$ result.lsoa                      : chr [1:6] "Worthing 008C" "Hackney 017B" "Croydon 024D" "Enfield 002E" ...
##   ..$ result.msoa                      : chr [1:6] "Worthing 008" "Hackney 017" "Croydon 024" "Enfield 002" ...
##   ..$ result.incode                    : chr [1:6] "9AW" "8HB" "4BE" "4RF" ...
##   ..$ result.outcode                   : chr [1:6] "BN14" "E5" "CR0" "EN1" ...
##   ..$ result.admin_district            : chr [1:6] "Worthing" "Hackney" "Croydon" "Enfield" ...
##   ..$ result.parish                    : chr [1:6] "Worthing, unparished area" "Hackney, unparished area" "Croydon, unparished area" "Enfield, unparished area" ...
##   ..$ result.admin_county              : chr [1:6] "West Sussex" NA NA NA ...
##   ..$ result.admin_ward                : chr [1:6] "Gaisford" "Homerton" "Waddon" "Turkey Street" ...
##   ..$ result.ccg                       : chr [1:6] NA "NHS City and Hackney" "NHS Croydon" "NHS Enfield" ...
##   ..$ result.nuts                      : chr [1:6] "West Sussex (South West)" "Hackney and Newham" "Croydon" "Enfield" ...
##   ..$ result.codes.admin_district      : chr [1:6] "E07000229" "E09000012" "E09000008" "E09000010" ...
##   ..$ result.codes.admin_county        : chr [1:6] "E10000032" "E99999999" "E99999999" "E99999999" ...
##   ..$ result.codes.admin_ward          : chr [1:6] "E05007698" "E05009376" "E05000167" "E05000211" ...
##   ..$ result.codes.parish              : chr [1:6] "E43000150" "E43000202" "E43000198" "E43000200" ...
##   ..$ result.codes.ccg                 : chr [1:6] "E38000213" "E38000035" "E38000040" "E38000057" ...
##   ..$ result.codes.nuts                : chr [1:6] "UKJ27" "UKI41" "UKI62" "UKI54" ...
person hrbrmstr    schedule 01.08.2016
comment
Прошу прощения за плохо написанную документацию по API. Я изменил их - специально упомянул, что запрос POST должен иметь тип содержимого application/json - person C Blanchard; 07.04.2017

Согласно документации пакета httr, вы должны необходимо установить параметр encode в json следующим образом:

url <- "https://api.postcodes.io/postcodes"
body <- list(a = 1, b = 2, c = 3)

# JSON encoded
r <- POST(url, body = body, encode = "json")

Чтобы увидеть фактический запрос, вы можете использовать параметр verbose() из интерактивной консоли:

POST(url, body = body, encode = "json", verbose())
person Dirk Vollmar    schedule 01.08.2016

Вы можете поместить любой массив JSON в формат R, который может проходить через httr следующим образом:

body <- fromJSON("{"postcodes":"[ \"EN14RF\", \"G428QN\", \"E58HB\", \"SA13UL\", \"Bn149aw\", \"CR04BE\" ]"}")

затем опубликуйте:

sample4 <- POST("https://api.postcodes.io/postcodes?q=[postcode]", 
body = body, 
encode = "json")
person Luke Holcomb    schedule 24.07.2019