【问题标题】:R httr post with headers带有标题的 R httr 帖子
【发布时间】:2021-06-14 10:57:00
【问题描述】:

我在 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())

【问题讨论】:

    标签: python r httr


    【解决方案1】:

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

    请注意,为了检索所需的响应,大多数提供的标头被证明是不必要的(或由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 年 6 月 21 日创建

    一些解释

    列表中的 JSON 与列表中的列表

    在此处查看命名列表和命名列表列表之间生成的 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 年 6 月 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 年 6 月 23 日创建

    【讨论】:

    • 谢谢!我对list of list 也有同样的怀疑,但无法真正验证和理解原因。如果您能向我指出一些资源以了解有关使用 R 和 Web 技术的更多信息,我将不胜感激。我浏览了小插图和文档,但无法真正得到这种解释。
    • 我同意 httr 文档有点不透明,并且小插图的范围有限。我想他们是为了简单起见,因为 httr 基于curl,它有大量文档。对 curl 了解得越多,就越容易弄清楚 httr。
    【解决方案2】:

    一般来说,当使用 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,这可能表明需要在请求中包含其他变量。

    【讨论】:

    • Error in request(headers = c(..., .headers)) : is.character(headers) is not TRUE 它期望 character 而不是 list
    • 你试过用c()而不是list()包装标题吗?
    • 如果我将 list()headers 修改为 c(),我会收到错误的请求 400
    • 你能给我一个真实的例子来测试吗?
    • 我已经相应地更新了帖子上的代码。请看看它是否有效
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多