Опубликовать запрос с использованием RCurl

#r #rcurl

#r #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 в другие части 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')
  

приведет к желаемым результатам.

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

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

Черт возьми, я использую R 2.13.0 на Mac 10.6.7.

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

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

Ответ №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:

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

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

Комментарии:

1. Спасибо за помощь! Есть ли какая-либо причина, по которой ключом является ‘a’? Я пробовал ‘name’, ‘text’ и кучу другой ерунды.

2. Исправление: я пытался использовать ‘name’ и т.д. в другом вызове. Я пытался использовать, например, postForm (api, строка), и вам нужна postForm (api, a = строка).

3. Правильно, вам нужно предоставить пару ключ = значение. ‘a’ был совершенно произвольным (это просто первая буква, которая пришла на ум). Любой из этих других работает так же хорошо (как a=»string», name =»string» и т.д. «a» = «string» не будет работать.)

4. Привет, я хочу сделать то же самое, что и вы, но мой тип содержимого «текстовый / обычный», возможно ли передать это в postForm?

Ответ №3:

От Дункана Темпла Ланга из списка R-help:

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

Ответ №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 . Это проблема с кодированием или что-то еще?

Комментарии:

1. Я бы предположил, что на самом деле это что-то на стороне API — это то, что вы ожидаете увидеть, если они странно обрабатывают URL-кодированные вещи. Вы могли бы попробовать использовать URLencode() в своем аргументе, но на самом деле это может не помочь.

Ответ №5:

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