Запрос POST с использованием RCurl

В качестве способа изучения того, как сделать пакет в R для Denver RUG, я решил, что было бы неплохим проектом написать R-обертку вокруг API datasciencetoolkit. Основные инструменты 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 другим частям API DSTK. Например,

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')

даст желаемые результаты.

Чтобы быть ясным, я прочитал документы RCurl на сайте DTL omegahat, документы RCurl с пакетом и страницу с завитушками. Тем не менее, я пропускаю что-то принципиальное относительно curl (или, возможно,.opts() в функции postForm()), и я не могу его получить.

В python я мог бы в принципе сделать "необработанный" запрос POST с использованием httplib.HTTPConnection - что-то подобное в R? Я также посмотрел на функцию simplePostToHost в пакете httpRequest, и он просто заблокировал мой сеанс R (для него также нужен ключ).

FWIW, я использую R 2.13.0 на Mac 10.6.7.

Любая помощь очень ценится. Весь код скоро будет доступен на github, если вы заинтересованы в том, чтобы поиграть с набором инструментов для научных исследований.

Приветствия.

Ответы

Ответ 1

С 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")

Ответ 2

Как правило, в тех случаях, когда вы пытаетесь выполнить POST, что не имеет ключа, вы можете просто назначить фиктивный ключ этому значению. Например:

> 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 и т.д.).

Ответ 3

Из Duncan Temple Lang в списке R-help:

postForm() использует другой стиль (или, конкретно, Content-Type) для представления формы, чем команда curl -d. Переключение стиля = '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.

Ответ 4

Я просто хотел указать, что должна быть проблема с передачей необработанной строки через функцию 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. Это проблема с кодировкой или чем-то?

Ответ 5

Функция simplePostToHost в пакете httpRequest может делать то, что вы ищете здесь.