2011-04-26 24 views
13

Como una forma de explorar cómo hacer un paquete en R para el Denver RUG, decidí que sería un pequeño proyecto divertido escribir un contenedor R alrededor de la API datasciencetoolkit. Las herramientas básicas R provienen del paquete RCurl como se puede imaginar. Estoy atrapado en un problema aparentemente simple y espero que alguien en este foro pueda apuntarme en la dirección correcta. El problema básico es que no puedo usar postForm() para pasar una cadena sin clave como parte de la opción de datos en curl, es decir curl -d "cadena" "dirección_a_api".Solicitud POST usando RCurl

Por ejemplo, desde la línea de comandos que podría hacer

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

con éxito. Sin embargo, parece que postForm() requiere una clave explícita al pasar argumentos adicionales a la solicitud POST. Revisé el código de datasciencetoolkit y los documentos de desarrollador para obtener una clave posible, pero parece que no encuentro nada.

Como un lado, es bastante sencillo pasar entradas a través de una solicitud GET a otras partes de la API DSTK. Por ejemplo,

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

producirá los resultados deseados.

Para ser claros, he leído los documentos de RCurl en el sitio omegahat de DTL, los documentos de RCurl con el paquete y la página del manual del curl. Sin embargo, me falta algo fundamental con respecto a curl (o quizás .opts() en la función postForm()) y parece que no puedo obtenerlo.

En python, básicamente podría hacer una solicitud POST 'sin procesar' usando httplib.HTTPConnection - ¿hay algo así como disponible en R? También miré la función simplePostToHost en el paquete httpRequest y pareció bloquear mi sesión R (parece que también requiere una clave).

FWIW, estoy usando R 2.13.0 en Mac 10.6.7.

Cualquier ayuda es muy apreciada. Todo el código estará disponible pronto en github si está interesado en jugar con el kit de herramientas de ciencia de datos.

Saludos.

Respuesta

15

Con HTTR, esto es sólo:

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

En general, en los casos en que intentas enviar algo que no está codificado, puedes asignarle una llave ficticia a ese valor. Por ejemplo:

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

funcionaría igual si había utilizado b = "Arzobispo Huxley", etc.

Disfruta RCurl - es probablemente mi favorita paquete R. Si se vuelve aventurero, la actualización a ~ libcurl 7.21 expone algunos métodos nuevos mediante curl (incluido SMTP, etc.).

+0

¡Gracias por la ayuda! ¿Hay alguna razón por la cual la clave es 'a'? Intenté con 'nombre', 'texto' y muchas otras cosas. – rtelmore

+0

Corrección: Intenté usar 'nombre', etc. en una llamada diferente. Intenté usar, p. Ej. postForm (api, cadena) y necesitas postForm (api, a = cadena). – rtelmore

+0

Correcto, debe proporcionar un par clave = valor. 'a' fue completamente arbitrario (es solo la primera letra que se le vino a la mente). Cualquiera de esos otros funciona igual de bien (como a = "cadena", nombre = "cadena", etc. "a" = "cadena" no funcionará). – Noah

1

Solo quería señalar que debe haber un problema al pasar una cadena sin formato a través de la función postForm. Por ejemplo, si uso rizo desde la línea de comandos, me sale el siguiente:

$ 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"}] 

y en RI obtener

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

Observe que devuelve dos elementos de la cadena JSON y ninguno de los dos partidos en el start_index o end_index. ¿Es esto un problema con la codificación o algo así?

+0

Supongo que esto es realmente algo en el extremo de la API: este es el tipo de cosas que esperarías ver si manejan cosas codificadas por URL extrañamente. Podría intentar usar URLencode() en su argumento, pero eso tal vez no ayude. – Noah

1

La función simplePostToHost en el paquete httpRequest puede hacer lo que está buscando aquí.

2

De Duncan Temple Lang en la lista R-ayuda:

postForm() es el uso de un estilo diferente (o específicamente Content-Type) de la presentación de la forma que el comando -d rizo. Cambiar el estilo = 'POST' utiliza el mismo tipo, pero en una suposición rápida, el nombre del parámetro 'a' está causando confusión y el resultado es la matriz JSON vacía - "[]".

Una solución rápida es utilizar curlPerform() directamente en lugar de postForm()

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

Esto produce

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

y se puede utilizar fromJSON() para transformarlos en datos en R.