2009-02-16 12 views
43

Ich versuche gerade, mich mit Python in eine Site einzuloggen, aber die Site scheint einen Cookie und eine Redirect-Anweisung auf derselben Seite zu senden. Python scheint dieser Weiterleitung zu folgen, was mich daran hindert, den Cookie zu lesen, der von der Anmeldeseite gesendet wurde. Wie verhindere ich, dass Pythons urllib (oder urllib2) urlopen der Weiterleitung folgt?Wie verhindere ich, dass Pythons urllib (2) einer Weiterleitung folgt

+0

Du plicate: http://stackoverflow.com/questions/110498/is-there-an-easy-way-to-request-a-url-in-python-and-not-follow-redirects/110808 –

+0

eine ähnliche Frage: http://stackoverflow.com/questions/9890815/python-get-headers-only-using-urllib2 – newtover

Antwort

33

Sie könnten ein paar Dinge tun:

  1. Ihre eigene HTTPRedirectHandler bauen, die jeder
  2. Erstellen Sie eine Instanz von HTTPCookieProcessor umleiten abfängt und diesen Opener installieren, so dass Sie Zugriff auf die cookiejar haben.

Dies ist eine kurze kleine Sache, die sowohl

import urllib2 

#redirect_handler = urllib2.HTTPRedirectHandler() 

class MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler): 
    def http_error_302(self, req, fp, code, msg, headers): 
     print "Cookie Manip Right Here" 
     return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers) 

    http_error_301 = http_error_303 = http_error_307 = http_error_302 

cookieprocessor = urllib2.HTTPCookieProcessor() 

opener = urllib2.build_opener(MyHTTPRedirectHandler, cookieprocessor) 
urllib2.install_opener(opener) 

response =urllib2.urlopen("WHEREEVER") 
print response.read() 

print cookieprocessor.cookiejar 
+0

Sie scheinen' redirect_handler = urllib2.HTTPRedirectHandler() 'im Beispiel überhaupt nicht zu verwenden. Würdest du ein zweites Beispiel zeigen? –

+0

Sie haben Recht, ich benutze den redirect_handler nicht. Stattdessen habe ich meinen eigenen Redirect-Handler erstellt. Ich werde bearbeiten, um zu entfernen. – pope

+0

Warum müssen Sie den 'MyHTTPRedirectHandler' nicht instanziieren, sondern die Klasse in die' build_opener() 'Methode übergeben? – Benjamin

11

urllib2.urlopen nennt build_opener(), die diese Liste der Handler-Klassen verwendet:

handlers = [ProxyHandler, UnknownHandler, HTTPHandler, 
HTTPDefaultErrorHandler, HTTPRedirectHandler, 
FTPHandler, FileHandler, HTTPErrorProcessor] 

Sie versuchen urllib2.build_opener(handlers) sich mit einer Liste aufrufen könnte, die HTTPRedirectHandler weglässt, dann rufen Sie die open() Methode auf das Ergebnis Ihrer URL zu öffnen. Wenn Sie Redirects wirklich nicht mögen, können Sie auch urllib2.install_opener(opener) zu Ihrem eigenen nicht-Redirector Opener aufrufen.

Es klingt wie Ihr echtes Problem ist, dass urllib2 Cookies nicht so macht, wie Sie möchten. Siehe auch How to use Python to login to a webpage and retrieve cookies for later usage?

+6

* Sie könnten versuchen, urllib2.build_opener (Handler) selbst mit einer Liste aufrufen, die HTTPRedirectHandler auslässt, dann rufen Sie die open() -Methode auf auf das Ergebnis, um Ihre URL zu öffnen. * Nun, Dokumente für urllib2.build_opener() say this * Instanzen der folgenden Klassen ** stehen vor den Handlern **, außer die Handler enthalten sie, Instanzen von ihnen oder Unterklassen von ihnen: ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler , HTTPErrorProcessor. * Es sieht so aus, als würde das Auslassen von 'HTTPRedirectHandler' nicht funktionieren ... –

3

Diese Frage wurde vor here gestellt.

EDIT: Wenn Sie mit skurrilen Web-Anwendungen beschäftigen müssen, sollten Sie wahrscheinlich mechanize ausprobieren. Es ist eine großartige Bibliothek, die einen Webbrowser simuliert. Sie können Weiterleitungen, Cookies, Seitenaktualisierungen steuern ... Wenn die Website nicht stark auf JavaScript angewiesen ist, kommen Sie sehr gut mit mechanize aus.

28

zeigt Wenn alles notwendige Umleitung ist zu stoppen, dann ist es eine einfache Möglichkeit, es zu tun. Zum Beispiel möchte ich nur Cookies bekommen und für eine bessere Leistung möchte ich nicht auf eine andere Seite weitergeleitet werden. Ich hoffe auch, dass der Code als 3xx gespeichert wird. Lassen Sie uns 302 zum Beispiel verwenden.

class MyHTTPErrorProcessor(urllib2.HTTPErrorProcessor): 

    def http_response(self, request, response): 
     code, msg, hdrs = response.code, response.msg, response.info() 

     # only add this line to stop 302 redirection. 
     if code == 302: return response 

     if not (200 <= code < 300): 
      response = self.parent.error(
       'http', request, response, code, msg, hdrs) 
     return response 

    https_response = http_response 

cj = cookielib.CookieJar() 
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj), MyHTTPErrorProcessor) 

Auf diese Weise brauchen Sie nicht einmal in urllib2.HTTPRedirectHandler.http_error_302 gehen müssen()

Noch häufiger Fall ist, dass wir einfach Umleitung beenden möchten (je nach Bedarf):

class NoRedirection(urllib2.HTTPErrorProcessor): 

    def http_response(self, request, response): 
     return response 

    https_response = http_response 

Und normalerweise benutzen es so aus:

cj = cookielib.CookieJar() 
opener = urllib2.build_opener(NoRedirection, urllib2.HTTPCookieProcessor(cj)) 
data = {} 
response = opener.open('http://www.example.com', urllib.urlencode(data)) 
if response.code == 302: 
    redirection_target = response.headers['Location'] 
+1

Genau das, was ich brauchte, und sehr präzise 'Klasse NoRedirection()' - Sie müssen nicht einmal 'Code, msg, hdrs' speichern - Danke Alan. –

+0

Sie haben Recht! Und ich habe die Zeile entfernt, wie du es vorgeschlagen hast. Danke Xtof. –

+0

Ist es möglich, diesen Ansatz zu verwenden, um die tatsächliche Weiterleitungs-URL zu erhalten? – AdjunctProfessorFalcon

Verwandte Themen