2009-09-01 6 views
19

Ich möchte die Cookies von einem Open-Uri-Anruf speichern und sie an den nächsten übergeben. Ich kann nicht die richtigen Dokumente dafür finden. Ich würde es begrüßen, wenn Sie mir den richtigen Weg dazu geben könnten.
ANMERKUNGEN: w3.org ist nicht die tatsächliche URL, aber es ist kürzer; täuschen Cookies vor Ruby's Open-URI und Cookies

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

Update nach 2 nays: Zwar ist dies nicht als rhetorische Frage gedacht war ich garantiere, dass es möglich ist. Update nach Tumbleweeds: Siehe (die Antwort), es ist möglich. Nahm mich eine Weile, aber es funktioniert.

+2

Für das, was Sie zu tun versuchen würde ich empfehlen, mit [Mechanize] (http://mechanize.rubyforge.org/mechanize/). Es ist für diese Art von Dingen konzipiert. Aus seiner Beschreibung: "Die Mechanize-Bibliothek wird zur Automatisierung der Interaktion mit Websites verwendet. Mechanize speichert und sendet automatisch Cookies, folgt Redirects, kann Links folgen und Formulare senden. Formularfelder können ausgefüllt und gesendet werden. Mechanize verfolgt auch die Websites, die Du hast als Geschichte besucht." –

+0

Das mechanisieren Link ist tot, hier ist der neue http://mechanize.rubyforge.org/ – MCB

+1

Mechanize ist jetzt auf GitHub: https://github.com/sparklemotion/mechanize – JESii

Antwort

26

Ich dachte, jemand würde nur wissen, aber ich denke, es mit open-uri getan nicht allgemein ist. Hier ist die hässliche Version, die weder überprüft für die Privatsphäre, Ablauf, die richtige Domäne, noch der richtige Pfad:

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

Ja, es funktioniert. Nein, es ist nicht schön, noch völlig konform mit Empfehlungen, noch behandelt es mehrere Cookies (wie es ist).

Offensichtlich HTTP ist ein sehr einfaches Protokoll, und open-uri können Sie höchstens davon. Ich denke, was ich wirklich wissen musste, war, wie man den Cookie von der h1 Anfrage bekommt, so dass er an die h2 Anfrage weitergegeben werden könnte (der Teil, den ich bereits kannte und zeigte). Das Überraschende hier ist, wie viele Leute im Grunde antworteten wollten, indem sie mir sagten, ich solle open-uri nicht verwenden, und nur einer davon zeigte, wie man einen Cookie in einer Anfrage an die nächste Anfrage weiterleitet.

1

Sie müssten Ihre eigene Cookie-Unterstützung rollen, indem Sie die Meta-Header analysieren, wenn Sie beim Senden einer Anfrage einen Cookie-Header lesen, wenn Sie open-uri verwenden. Erwägen Sie die Verwendung von httpclient http://raa.ruby-lang.org/project/httpclient/ oder etwas wie mechanize statt http://mechanize.rubyforge.org/, wie sie Cookie-Unterstützung eingebaut haben.

+0

Ich fürchte," keine Unterstützung für Cookies "ist zu stark von einer Auswahl von Wörtern. Ich schätze die Links though. Die Dokumentation des letzteren scheint spärlich. http://mechanize.rubyforge.org/mechanize/WWW/Mechanize/CookieJar.html – dlamblin

+0

Rubys Mechanize ist eng auf Perl basiert WWW :: Mechanize, das einige nette Dokumente hat. Die Beschreibung von Cookies in den Perl-Dokumenten sollte helfen, herauszufinden, wie die Ruby-Version funktioniert. Es ist eine Weile her, seit ich sie benutzt habe, aber ich denke, sie wird ein Keksglas liefern Handle sie automatisch.Sie können Ihre eigenen jar definieren, wenn Sie sie in oder aus wechseln oder auf der Festplatte speichern für die spätere Wiederverwendung. –

12

Sie müssen einen "Cookie" Header hinzufügen.

Ich bin nicht sicher, ob Open-Uri dies tun kann oder nicht, aber es kann mit Net :: HTTP getan werden.

# 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

Ja, open-URI kann zusätzliche Header senden: öffnen (URL, "Cookie" => Cookie) # http://www.ru by-doc.org/stdlib/libdoc/open-uri/rdoc/classes/OpenURI.html –

+0

Berücksichtigt diese Net :: HTTP-Version den Ablauf, den Pfad oder die Domain des Cookies? – dlamblin

+0

@dlamblin Nein, absichtlich nicht. Lernen Sie zuerst zu krabbeln, dann zu laufen und dann zu rennen. –

2

Je nachdem, was Sie erreichen möchten, überprüfen Sie webrat. Ich weiß, dass es normalerweise zum Testen verwendet wird, aber es kann auch Live-Sites treffen, und es macht eine Menge von den Sachen, die Ihr Web-Browser für Sie tun würde, wie Cookies zwischen Anfragen speichern und Redirects folgen.

+2

Ich würde stattdessen Mechanize empfehlen. Es wird Live-Sites treffen, Cookies handhaben und Redirects folgen, und es wurde tatsächlich entwickelt, um all das zu tun. –

4

Danke Matthew Schinckel deine Antwort war wirklich hilfreich. Mit Net :: HTTP ich war erfolgreich

 # 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