2009-09-01 13 views
19

Me gustaría guardar las cookies de una llamada abierta-uri y pasarlas a la siguiente. Parece que no puedo encontrar los documentos correctos para hacer esto. Te agradecería si pudieras decirme la manera correcta de hacer esto.
NOTAS: w3.org no es la url real, pero es más corta; pretender cookies importan aquí.Ruby's open-uri y cookies

h1 = open("http://www.w3.org/") 
h2 = open("http://www.w3.org/People/Berners-Lee/", "Cookie" => h1.FixThisSpot) 

actualización después de 2 votos en contra: Si bien esto no fue pensado como pregunta retórica Te garantizo que es posible. Actualización después de tumbleweeds: Ver (la respuesta), es posible. Me tomó un buen rato, pero funciona.

+2

Por lo que estamos tratando de hacer le recomiendo usar [Mechanize] (http://mechanize.rubyforge.org/mechanize/). Está diseñado para este tipo de cosas. De su descripción: "La biblioteca Mechanize se usa para automatizar la interacción con sitios web. Mechanize almacena y envía cookies automáticamente, sigue redirecciones, puede seguir enlaces y enviar formularios. Los campos de formulario se pueden llenar y enviar. Mechanize también realiza un seguimiento de los sitios que has visitado como una historia." –

+0

Ese enlace mecanizado está muerto, aquí está el nuevo http://mechanize.rubyforge.org/ – MCB

+1

Mechanize está ahora en github: https://github.com/sparklemotion/mechanize – JESii

Respuesta

26

pensé que alguien acaba de conocer, pero yo supongo que no es comúnmente realiza con open-uri. Aquí está la versión fea que ni los controles de privacidad, la expiración, el dominio correcto, ni el camino correcto:

h1 = open("http://www.w3.org/") 
h2 = open("http://www.w3.org/People/Berners-Lee/", 
      "Cookie" => h1.meta['set-cookie'].split('; ',2)[0]) 

sí, funciona. No, no es bonito, ni cumple totalmente con las recomendaciones, ni maneja múltiples cookies (como está).

Claramente, HTTP es un protocolo muy sencillo, y open-uri le permite la mayor parte. Creo que lo que realmente necesitaba saber era cómo obtener la cookie de la solicitud h1 para que se pudiera pasar a la solicitud h2 (esa parte que ya conocía y mostraba). Lo sorprendente aquí es cuántas personas básicamente tuvieron ganas de responder diciéndome que no use open-uri, y solo una de ellas mostró cómo obtener un conjunto de cookies en una solicitud que se pasó a la próxima solicitud.

1

tendrías que hacer rodar tu propio soporte de cookies analizando los encabezados de los metadatos al leer y agregar un encabezado de cookie al enviar una solicitud si estás usando open-uri. Considere el uso de httpclient http://raa.ruby-lang.org/project/httpclient/ o algo así como mecanizar en su lugar http://mechanize.rubyforge.org/ ya que tienen soporte para cookies integrado.

+0

Me temo que" no admite cookies " "es demasiado fuerte de una elección de palabras. Aunque aprecio los enlaces. La documentación de este último parece escasa. http://mechanize.rubyforge.org/mechanize/WWW/Mechanize/CookieJar.html – dlamblin

+0

Ruby's Mechanize está estrechamente basado en Perl's WWW :: Mechanize, que tiene algunos buenos documentos. La descripción de las cookies en los documentos de Perl debería ayudar a descubrir cómo funciona la versión de Ruby. Ha pasado un tiempo desde que lo usé, pero creo que proporcionará un contenedor de cookies y lo hará manipúlelos automáticamente. Puede definir su propio jar si quiere encenderlos o guardarlos o almacenarlos en el disco para su posterior reutilización. –

12

Debe agregar un encabezado "Cookie".

No estoy seguro si open-uri puede hacer esto o no, pero se puede hacer usando Net :: HTTP.

# Create a new connection object. 
conn = Net::HTTP.new(site, port) 

# Get the response when we login, to set the cookie. 
# body is the encoded arguments to log in. 
resp, data = conn.post(login_path, body, {}) 
cookie = resp.response['set-cookie'] 

# Headers need to be in a hash. 
headers = { "Cookie" => cookie } 

# On a get, we don't need a body. 
resp, data = conn.get(path, headers) 
+2

Sí, open-uri puede enviar encabezados adicionales: open (url, "Cookie" => cookie) # http://www.ru by-doc.org/stdlib/libdoc/open-uri/rdoc/classes/OpenURI.html –

+0

¿Tiene en cuenta esta versión Net :: HTTP la caducidad, la ruta o el dominio de las cookies? – dlamblin

+0

@dlamblin No, deliberadamente no. Primero, aprende a gatear, luego caminar y luego correr. –

2

Según lo que esté tratando de lograr, consulte webrat. Sé que generalmente se usa para probar, pero también puede llegar a los sitios en vivo, y hace muchas cosas que su navegador web haría por usted, como almacenar cookies entre solicitudes y seguir redireccionamientos.

+2

Recomendaría Mechanize en su lugar. Golpeará los sitios en vivo, manejará las cookies y seguirá los redireccionamientos, y, en realidad, fue diseñado para hacer todo eso. –

4

Gracias Matthew Schinckel su respuesta fue realmente útil. El uso de Net :: HTTP tuve éxito

 # Create a new connection object. 
      site = "google.com" 
      port = 80 
      conn = Net::HTTP.new(site, port) 

     # Get the response when we login, to set the cookie. 
     # body is the encoded arguments to log in. 
      resp, data = conn.post(login_path, body, {}) 
      cookie = resp.response['set-cookie'] 

     # Headers need to be in a hash. 
      headers = { "Cookie" => cookie } 

     # On a get, we don't need a body. 
      resp, data = conn.get(path, headers) 

      puts resp.body