R httr post 与 headers

R httr post with headers

我在 Python 中有以下请求。我如何在 Rhttr 包中重写它?

我不确定的是如何翻译 R 中的 jsontuple 等价物。

import requests

cookies = {}

headers = {
    'Host': 'mysejahtera.malaysia.gov.my',
    'Accept': 'application/json',
    'Connection': 'keep-alive',
    'Content-Length': '77',
    'Authorization': 'Basic N0ZFRkRCMTMtN0Q2MC00NEQxLUE5MTctM0',
    'Content-Type': 'application/json',
    'Accept-Language': 'en-MY;q=1, ms-MY;q=0.9',
    'User-Agent': 'MySejahtera/1.0.36 (iPhone; iOS 14.6; Scale/2.00)',
}

params = (
    ('type', 'search'),
)

data = '[{"lat":3.003090,"lng":101.678300,"classification":"LOW_RISK_NS"}]'

response = requests.post('https://mysejahtera.malaysia.gov.my/register/api/nearby/hotspots', headers=headers, params=params, cookies=cookies, data=data)
response.json()

这是一次尝试。但是还是给出了400错误的请求

POST("https://mysejahtera.malaysia.gov.my/register/api/nearby/hotspots?type=search",
     body = list(lat = 3.003090, lng = 101.678300, classification = 'LOW_RISK_NS'), 
     add_headers(Host= 'mysejahtera.malaysia.gov.my',
                 Accept= 'application/json',
                 Connection= 'keep-alive',
                 `Content-Length`= '77',
                 Authorization= 'Basic N0ZFRkRCMTMtN0Q2MC00NEQxLUE5MTctM0',
                 `Content-Type`= 'application/json',
                 `Accept-Language`= 'en-MY;q=1, ms-MY;q=0.9',
                 `User-Agent`= 'MySejahtera/1.0.36 (iPhone; iOS 14.6; Scale/2.00)'), verbose())

一般来说,我在使用 R 进行网页抓取时将输入值设置在 list() 或向量 c() 中。

httr 的 POST() 也接受 JSON 作为正文,正如您在 documentation.

上看到的那样

您的代码很可能如下所示:

library(httr)

cookies <- c()

headers <- c('Host' = 'mysejahtera.malaysia.gov.my',
             'Accept' = 'application/json',
             'Connection' = 'keep-alive',
             'Content-Length' = '77',
             'Authorization' = 'Basic N0ZFRkRCMTMtN0Q2MC00NEQxLUE5MTctM0',
             'Content-Type' = 'application/json',
             'Accept-Language' = 'en-MY;q=1, ms-MY;q=0.9',
             'User-Agent' = 'MySejahtera/1.0.36 (iPhone; iOS 14.6; Scale/2.00)')

data <- list("type" = "search",
             "lat" = 3.003090,
             "lng" = 101.678300,
             "classification" = "LOW_RISK_NS")

response = POST("https://mysejahtera.malaysia.gov.my/register/api/nearby/hotspots",
                body = data,
                add_headers(.headers = headers))

我已将 params 合并到 body 中,并且删除了 cookie,因为当它们为空时会抛出错误。

状态代码仍然是 400,这可能表明需要在请求中包含其他变量。

这里的技巧似乎是将数据构造为命名列表的列表,以便按照 API 的预期将其编码为 json。

请注意,大多数提供的 headers 被证明是不必要的(或由 httr 自动生成)以检索所需的响应。

library(httr)

# data as list of named list
data <- list(
  list(
    lat = 3.003090,
    lng = 101.678300,
    classification = "LOW_RISK_NS"
  )
)

params <- list(type = "search")

response <- POST("https://mysejahtera.malaysia.gov.my/register/api/nearby/hotspots",
                 query = params,
                 body = data, 
                 add_headers(Authorization = "Basic N0ZFRkRCMTMtN0Q2MC00NEQxLUE5MTctM0"),
                 encode = "json"
)
content(response)
#> $hotSpots
#> list()
#> 
#> $zoneType
#> [1] "RED"
#> 
#> $messages
#> $messages$ms_MY
#> [1] "Hai {name}, terdapat 21 kes COVID-19 dalam lingkungan radius 1km dari lokasi ini yang dilaporkan dalam masa 14 hari yang lepas."
#> 
#> $messages$en_US
#> [1] "Hi {name}, there have been 21 reported case(s) of COVID-19 within a 1km radius from your searched location in the last 14 days."
#> 
#> 
#> $note
#> NULL

reprex package (v1.0.0)

创建于 2021-06-21

一些解释

JSON 来自 List 与 List of List

在此处查看命名列表和命名列表的列表之间 json 的结果字符串中的差异(即添加方括号):

data <- list(lat = 3, lng = 101, class = "LOW")

# list
jsonlite::toJSON(data)
#> {"lat":[3],"lng":[101],"class":["LOW"]}

# list of a named list
jsonlite::toJSON(list(data))
#> [{"lat":[3],"lng":[101],"class":["LOW"]}]

reprex package (v1.0.0)

于 2021-06-23 创建

更简单的方法

这里我自己做了更多的编码工作,而不是让 httr 像上面的答案那样处理它。

请注意,与上面的第二个(列表的列表)json 字符串相比,值周围的方括号现在丢失了。这是“拆箱”的代表httr

library(httr)

response <- POST("https://mysejahtera.malaysia.gov.my/register/api/nearby/hotspots?type=search",
                 body = '[{"lat":3.003090,"lng":101.678300,"classification":"LOW_RISK_NS"}]', 
                 add_headers(Authorization = "Basic N0ZFRkRCMTMtN0Q2MC00NEQxLUE5MTctM0",
                             "Content-Type" = "application/json")
)
content(response)
#> $hotSpots
#> list()
#> 
#> $zoneType
#> [1] "RED"
#> 
#> $messages
#> $messages$ms_MY
#> [1] "Hai {name}, terdapat 22 kes COVID-19 dalam lingkungan radius 1km dari lokasi ini yang dilaporkan dalam masa 14 hari yang lepas."
#> 
#> $messages$en_US
#> [1] "Hi {name}, there have been 22 reported case(s) of COVID-19 within a 1km radius from your searched location in the last 14 days."
#> 
#> 
#> $note
#> NULL

reprex package (v1.0.0)

于 2021-06-23 创建