2009-09-01 21 views
19

Vorrei memorizzare i cookie da una chiamata open-uri e passarli a quella successiva. Non riesco a trovare i documenti giusti per farlo. Lo apprezzerei se potessi dirmi il modo giusto per farlo.
NOTE: w3.org non è l'url effettivo, ma è più breve; fingere che i biscotti contengano qui.Apri-uri e biscotti di Ruby

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

Aggiornamento dopo 2 nays: Anche se questo non è stato inteso come domanda retorica vi garantisco che è possibile. Update after tumbleweeds: Vedere (la risposta), è possibile. Mi ci è voluto un bel po ', ma funziona.

+2

Per quello che si sta cercando di fare mi consiglia di utilizzare [Mechanize] (http://mechanize.rubyforge.org/mechanize/). È progettato per questo genere di cose. Dalla sua descrizione: "La libreria Mechanize viene utilizzata per automatizzare l'interazione con i siti Web. Mechanize memorizza e invia automaticamente i cookie, segue i reindirizzamenti, può seguire i collegamenti e inviare moduli.I campi del modulo possono essere compilati e inviati. hai visitato come una storia." –

+0

Questo link di mechanize è morto, eccone il nuovo http://mechanize.rubyforge.org/ – MCB

+1

Mechanize è ora su github: https://github.com/sparklemotion/mechanize – JESii

risposta

26

Ho pensato che qualcuno sarebbe solo sapere, ma immagino che non è comunemente fatto con open-uri. Ecco la versione brutta che né i controlli per la privacy, la scadenza, il dominio corretto, né il percorso corretto:

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

Sì, funziona. No non è bello, né pienamente conforme alle raccomandazioni, né gestisce più cookie (come è).

Chiaramente, HTTP è un protocollo molto semplice, e lo standard open-uri ti consente al massimo. Immagino che quello che dovevo sapere era come ottenere il cookie dalla richiesta h1 in modo che potesse essere passato alla richiesta h2 (quella parte che conoscevo e mostravo già). La cosa sorprendente qui è il modo in cui molte persone hanno praticamente avuto voglia di rispondere dicendomi di non usare open-uri, e solo una di quelle ha mostrato come ottenere un set di cookie in una richiesta passata alla successiva richiesta.

1

si dovrebbe rollare il proprio supporto cookie analizzando le meta header quando si legge e si aggiunge un'intestazione del cookie quando si invia una richiesta se si utilizza open-uri. Considera l'uso di httpclient http://raa.ruby-lang.org/project/httpclient/ o qualcosa come mechanize invece http://mechanize.rubyforge.org/ in quanto hanno il supporto dei cookie integrato.

+0

Ho paura" nessun supporto per i cookie "è troppo forte per una scelta di parole, tuttavia apprezzo i collegamenti. La documentazione di quest'ultimo sembra scarsa. http://mechanize.rubyforge.org/mechanize/WWW/Mechanize/CookieJar.html – dlamblin

+0

Ruby's Mechanize è strettamente basato su Perl WWW :: Mechanize, che ha alcuni buoni documenti, la descrizione dei cookie nei documenti Perl dovrebbe aiutare a capire come funziona la versione di Ruby. È passato un po 'di tempo da quando l'ho usato, ma penso che fornirà un cookie jar e gestiscili automaticamente Puoi definire il tuo jar se vuoi cambiarli o salvarli o salvarli su disco per riutilizzarli in seguito. –

12

È necessario aggiungere un'intestazione "Cookie".

Non sono sicuro che open-uri possa farlo oppure no, ma può essere fatto utilizzando 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 può inviare intestazioni aggiuntive: open (url, "Cookie" => cookie) # http://www.ru by-doc.org/stdlib/libdoc/open-uri/rdoc/classes/OpenURI.html –

+0

Questa versione di Net :: HTTP prende in considerazione la scadenza, il percorso o il dominio dei cookie? – dlamblin

+0

@dlamblin No, deliberatamente no. Per prima cosa, impara a gattonare, poi cammina, poi corri. –

2

A seconda di cosa si sta tentando di eseguire, controlla webrat. So che di solito viene usato per i test, ma può anche colpire siti live e fa un sacco di cose che il tuo browser web farebbe per te, come memorizzare i cookie tra le richieste e seguire i reindirizzamenti.

+2

Suggerirei invece Mechanize. Colpirà i siti live, gestirà i cookie e seguirà anche i reindirizzamenti e, in realtà, è stato progettato per fare tutto ciò. –

4

Grazie Matthew Schinckel la tua risposta è stata davvero utile. Utilizzando Net :: HTTP ho avuto successo

 # 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