Python/urlgrabber kriegt anderen Content als Browser

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
abaum
User
Beiträge: 18
Registriert: Freitag 12. Januar 2007, 21:53
Kontaktdaten:

Freitag 12. Januar 2007, 22:37

Hallo,
ich versuche mich gerade an meinem ersten "richtigen" Python-Script. Es geht darum, von einer passwortgeschützten (keine HTTP-Authentifizierung) Seite ein PDF herunterzuladen. Dazu logge ich mich mit meinem Browser ein (Cookies deaktiviert) und hole mir die Session ID aus der URL... diese kopiere ich dann in mein Script. Obwohl die Authentifizierung ausschließlich mit der SID zusammenhängt, kriegt mein Script immer nur eine Login-Seite, während der Browser das PDF downloaden kann.
Mein Code:

Code: Alles auswählen

sid='479205305718508197'

from urlgrabber.grabber import URLGrabber
grabber = URLGrabber()

for i in range(1,5):
    user_agent = 'Opera/9.10 (Windows NT 5.1; U; en)'
    proxies = {'http' : 'http://localhost:8080'}
    http_headers = (('Accept', 'text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1'), ('Accept-Charset', 'iso-8859-1, utf-8, utf-16, *;q=0.1'), ('Accept-Encoding', 'deflate, gzip, x-gzip, identity, *;q=0'), ('TE', 'deflate, gzip, chunked, identity, trailers'))
    url = 'http://www.stol.it/dolomiten/news/pdf_page.asp?SID=%s&y=2007&m=01&d=12&f=01&ext=.pdf' % (sid)
    
    data = grabber.urlread(url, proxies=proxies, http_headers=http_headers, user_agent=user_agent)
    f = file('dateiname.pdf', 'w')
    f.write(data)
    f.close()
Hier zum Vergleich die Header (mit Hilfe des Proxys mitgeschnitten):
Anfrage Webbrowser (Opera) + Antwort

Code: Alles auswählen

GET /dolomiten/news/pdf_page.asp?SID=479205305718508197&y=2007&m=01&d=12&f=01&ext=.pdf HTTP/1.1
User-Agent: Opera/9.10 (Windows NT 5.1; U; de)
Host: www.stol.it
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: de-DE,de;q=0.9,en;q=0.8
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
TE: deflate, gzip, chunked, identity, trailers
Connection: keep-alive

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Fri, 12 Jan 2007 21:33:23 GMT
Connection: close
Content-Type: application/pdf
Set-Cookie: ASPSESSIONIDSQCASSDA=PMKLGJPBBJINGLKGOIGCNPGI; path=/
Cache-control: private
Und Python:

Code: Alles auswählen

GET /dolomiten/news/pdf_page.asp?SID=479205305718508197&y=2007&m=01&d=12&f=01&ext=.pdf HTTP/1.1
Host: www.stol.it
Accept-Encoding: identity
Accept-encoding: deflate, gzip, x-gzip, identity, *;q=0
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
User-agent: Opera/9.10 (Windows NT 5.1; U; en)
Accept-charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Te: deflate, gzip, chunked, identity, trailers
Connection: keep-alive

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Fri, 12 Jan 2007 21:35:00 GMT
Content-Length: 23547
Content-Type: text/html
Set-Cookie: ASPSESSIONIDSQCASSDA=EBLLGJPBGDHDMCFCILMBLMPN; path=/
Cache-control: private
Kann das jemand von euch nachvollziehen?
Vielen Dank,

Andreas
Zuletzt geändert von abaum am Samstag 13. Januar 2007, 21:18, insgesamt 1-mal geändert.
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Samstag 13. Januar 2007, 08:59

Nachvollziehen kann ich es im Moment eigentlich auch nicht, aber hier hab ich eine Klasse gepostet, mit der ich solche Sachen erledige: http://www.python-forum.de/topic-8580.html
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Samstag 13. Januar 2007, 09:44

Warscheinlich wird die SID mit Hilfe des User Agents gesaltet. DH: Du musst die Authentifizierung nochmal im Skript machen: Einloggen, SID speichern, runterladen. Kontrolliere vor allem ob die SID nicht noch zusätzlich als Cookie drin ist.
TUFKAB – the user formerly known as blackbird
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Samstag 13. Januar 2007, 10:01

Der UserAgent ist ja eigentl. gefaked und Cookies sind deaktiviert
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
abaum
User
Beiträge: 18
Registriert: Freitag 12. Januar 2007, 21:53
Kontaktdaten:

Samstag 13. Januar 2007, 11:14

Jetzt klappts, der User-Agent war nicht identisch, was wohl tatsächlich in der Session nochmal überprüft wird. Jetzt klappts - eigentlich...
Jetzt kriege ich zwar auch das PDF, allerdings hauts da wahllos Leerzeichen/Newlines rein...
Bild
Die beiden Dateien können hier heruntergeladen werden: PDF gespeichert von Opera und Python.
Ich vermute, dass es mit den nicht identischen "Accept-Encoding" und "TE"-Headern zusammenhängt. Allerdings bringe ich Python einfach nicht dazu, die Groß-Klein-Schreibung unverändert zu lassen...?

Edit: Ich muss die Datei im Binärmodus schreiben ("wb").. jetzt klappts, hurra! Danke für eure Hilfe!
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Samstag 13. Januar 2007, 15:24

dein User Agent Browser war Deutsch und der User Agent Python war Englisch.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Samstag 13. Januar 2007, 15:26

abaum hat geschrieben:Jetzt klappts, der User-Agent war nicht identisch, was wohl tatsächlich in der Session nochmal überprüft wird. Jetzt klappts - eigentlich...
Aber jedes mal, wenn du dich neu anmeldest bekommst du eine neue SID. Wenn du das Auth Handling nicht in deinem Skript machst musst du jedes Mal vor dem downloaden (ich nehme an du willst das öfter machen) die neue SID und den aktuellen User Agent eintragen. Was spricht dagegen das im Skript zu machen?
TUFKAB – the user formerly known as blackbird
abaum
User
Beiträge: 18
Registriert: Freitag 12. Januar 2007, 21:53
Kontaktdaten:

Samstag 13. Januar 2007, 15:28

Genau. Ich hatte das ganz am Anfang umgestellt, damit ich die HTTP-Logs voneinander unterscheiden kann.
Mein Script funktioniert jetzt soweit. Trotzdem stelle ich mir immer noch die Frage, wieso Python aus meinem "TE" ein "Te" macht..?
abaum
User
Beiträge: 18
Registriert: Freitag 12. Januar 2007, 21:53
Kontaktdaten:

Samstag 13. Januar 2007, 15:30

blackbird hat geschrieben:Was spricht dagegen das im Skript zu machen?
Ganz einfach - ich kann es noch nicht ;-) Aber das wird wirklich der nächste Punkt, den ich mir vornehme. Ich hatte mir das so gedacht, dass ich die Logindaten per POST übermittle und mir dann die SID irgendwie hole. Der User-Agent bleibt ja derselbe.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Samstag 13. Januar 2007, 16:16

abaum hat geschrieben:Trotzdem stelle ich mir immer noch die Frage, wieso Python aus meinem "TE" ein "Te" macht..?
Weil header case insensitive sind, und der programmierer der lib sich für title() statt lower() entschieden hat.
TUFKAB – the user formerly known as blackbird
abaum
User
Beiträge: 18
Registriert: Freitag 12. Januar 2007, 21:53
Kontaktdaten:

Samstag 13. Januar 2007, 21:19

Ok, dankeschön. Ich dachte, das ist ein Feature von Python, so wie die Leerzeichen bei der Stringverkettung mit dem Komma.
Antworten