使用RCurl的POST请求

时间:2011-04-26 23:35:31

标签: r rcurl

作为一种探索如何在R中为Denver RUG创建包的方法,我决定在datasciencetoolkit API周围编写一个R包装器是一个有趣的小项目。基本的R工具来自RCurl包,如您所想。我被困在一个看似简单的问题上,我希望这个论坛中的某个人能够指出我正确的方向。基本问题是我似乎无法使用postForm()将未键控的字符串作为curl中数据选项的一部分传递,即curl -d“string”“address_to_api”。

例如,从命令行我可以做

$ curl -d "Tim O'Reilly, Archbishop Huxley" "http://www.datasciencetoolkit.org/text2people"

成功。但是,似乎postForm()在将其他参数传递给POST请求时需要显式键。我查看了datasciencetoolkit代码和开发人员文档以获取可能的密钥,但似乎找不到任何东西。

顺便说一下,通过GET请求将输入传递给DSTK API的其他部分非常简单。例如,

ip2coordinates <- function(ip) {
  api <- "http://www.datasciencetoolkit.org/ip2coordinates/"
  result <- getURL(paste(api, URLencode(ip), sep=""))
  names(result) <- "ip"
  return(result)
}
ip2coordinates('67.169.73.113')

将产生预期的结果。

为了清楚起见,我已经阅读了DTL的omegahat网站上的RCurl文档,包含RCurl文档以及curl手册页。但是,我遗漏了一些关于curl(或者postForm()函数中的.opts())的基本内容,我似乎无法得到它。

在python中,我基本上可以使用httplib.HTTPConnection创建一个'原始'POST请求 - 就像R中可用的那样?我也查看了httpRequest包中的simplePostToHost函数,它似乎只是锁定了我的R会话(它似乎也需要一个键)。

FWIW,我在Mac 10.6.7上使用R 2.13.0。

非常感谢任何帮助。如果您对使用数据科学工具包感兴趣,所有代码很快就会在github上提供。

干杯。

5 个答案:

答案 0 :(得分:18)

使用httr,这只是:

library(httr)
r <- POST("http://www.datasciencetoolkit.org/text2people", 
  body = "Tim O'Reilly, Archbishop Huxley")
stop_for_status(r)
content(r, "parsed", "application/json")

答案 1 :(得分:6)

通常,在您尝试发布未键入的内容的情况下,您只需为该值分配一个虚拟键即可。例如:

> postForm("http://www.datasciencetoolkit.org/text2people", a="Archbishop Huxley")
[1] "[{\"gender\":\"u\",\"first_name\":\"\",\"title\":\"archbishop\",\"surnames\":\"Huxley\",\"start_index\":44,\"end_index\":61,\"matched_string\":\"Archbishop Huxley\"},{\"gender\":\"u\",\"first_name\":\"\",\"title\":\"archbishop\",\"surnames\":\"Huxley\",\"start_index\":88,\"end_index\":105,\"matched_string\":\"Archbishop Huxley\"}]"
attr(,"Content-Type")
                charset 
"text/html"     "utf-8" 

如果我使用b =“大主教赫胥黎”等,会有同样的效果。

享受RCurl - 这可能是我最喜欢的R套餐。如果您喜欢冒险,升级到~libcurl 7.21会通过curl(包括SMTP等)公开一些新方法。

答案 2 :(得分:2)

来自R-help名单上的Duncan Temple Lang:

postForm()使用与curl -d命令不同的样式(或特别是Content-Type)提交表单。 切换style ='POST'使用相同的类型,但是在快速猜测时,参数名称'a'会引起混淆 结果是空的JSON数组 - “[]”。

快速解决方法是直接使用curlPerform()而不是postForm()

r = dynCurlReader()
curlPerform(postfields = 'Archbishop Huxley', url = 'http://www.datasciencetoolkit.org/text2people', verbose = TRUE,
             post = 1L, writefunction = r$update)
r$value()

这会产生

[1]
"[{\"gender\":\"u\",\"first_name\":\"\",\"title\":\"archbishop\",\"surnames\":\"Huxley\",\"start_index\":0,\"end_index\":17,\"matched_string\":\"Archbishop
Huxley\"}]"

您可以使用fromJSON()将其转换为R中的数据。

答案 3 :(得分:1)

我只想指出通过postForm函数传递原始字符串一定存在问题。例如,如果我从命令行使用curl,我会得到以下内容:

    $ curl -d "Archbishop Huxley" "http://www.datasciencetoolkit.org/text2people
[{"gender":"u","first_name":"","title":"archbishop","surnames":"Huxley","start_index":0,"end_index":17,"matched_string":"Archbishop Huxley"}]

在R中我得到

> api <- "http://www.datasciencetoolkit.org/text2people"
> postForm(api, a="Archbishop Huxley")
[1] "[{\"gender\":\"u\",\"first_name\":\"\",\"title\":\"archbishop\",\"surnames\":\"Huxley\",\"start_index\":44,\"end_index\":61,\"matched_string\":\"Archbishop Huxley\"},{\"gender\":\"u\",\"first_name\":\"\",\"title\":\"archbishop\",\"surnames\":\"Huxley\",\"start_index\":88,\"end_index\":105,\"matched_string\":\"Archbishop Huxley\"}]"
attr(,"Content-Type")
                charset 
"text/html"     "utf-8" 

请注意,它返回JSON字符串中的两个元素,并且在start_index或end_index上都没有匹配。这是编码或其他什么问题吗?

答案 4 :(得分:1)

httpRequest包中的simplePostToHost函数可能会在此处执行您所需的操作。