16

作为探索如何在 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 上提供。

干杯。

4

5 回答 5

21

使用 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")
于 2014-07-30T20:37:37.637 回答
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="Archbishop Huxley" 等,效果会相同。

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

于 2011-04-27T01:03:08.290 回答
2

来自 R-help 列表上的 Duncan Temple Lang:

postForm() 使用与 curl -d 命令不同的提交表单的样式(或特别是 Content-Type)。切换样式 = '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 中的数据。

于 2011-04-30T16:05:10.787 回答
1

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

于 2011-04-28T16:58:42.087 回答
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"}]

并在 RI 中得到

> 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 匹配。这是编码的问题还是什么?

于 2011-04-28T15:17:58.410 回答