Webseiten-Quelltext eines RSS-Feeds mit Passwort lesen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
above
User
Beiträge: 3
Registriert: Dienstag 20. November 2012, 00:07

Hallo!
Ich bin schon lange am Suchen und mich durch die Python-Dokus wühlen, aber finde so recht keine Antwort zu meinem Problem, nicht einmal in Python 2.

Mit folgendem Code lese ich den Quelltext eines RSS-Feeds aus:

Code: Alles auswählen

import urllib

url = "http://somesite.de/feed.php"
response = urllib.request.urlopen(url)
print(response.read().decode()
Das funktioniert auch ohne Probleme, mir wird der Seitenquelltext ohne Probleme angezeigt.

Nun möchte ich aber auf einen RSS-Feed zugreifen, für den ich einen Login, also Username + Password brauche. Der Code für eine normale Webseite, bei der man sich einloggen muss, sieht bei mir so aus:

Code: Alles auswählen

import urllib
import http.cookiejar
url = "http://pagewithlogin.com"
values = {'user' : 'whatever',
          'passwrd' : '-------' } 

data = urllib.parse.urlencode(values)
cookies = http.cookiejar.CookieJar()

opener = urllib.request.build_opener(
    urllib.request.HTTPRedirectHandler(),
    urllib.request.HTTPHandler(debuglevel=0),
    urllib.request.HTTPSHandler(debuglevel=0),
    urllib.request.HTTPCookieProcessor(cookies))

response = opener.open(url, data.encode())

response = urllib.request.urlopen(url)
print(response.read().decode("utf-8", "replace"))
Das klappt auch ganz gut für die meisten Seiten.

Nur frage ich mich jetzt: Welche Parameter (also values = {"name1" : "bla", "name2" : bla}) muss ich bei einem passwortgeschützen RSS-Feed übergeben oder wie funktioniert es sonst?
(Habe es schon mit vielen Varianten von "User" und "Password" probiert, scheint aber auch nicht zu klappen. Nach meinem Verständnis ist dies auch nur für Elemente auf einer Webseite, also z.B. Textboxen, weswegen der Versuch eh sinnlos war.)
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Das lässt sich nicht pauschal sagen. Je nachdem wie der Passwortschutz aufgebaut ist, kann es sein, dass du Daten so wie hier angegeben übermitteln musst, in dem Fall müsste man sich in einer Webseite vorher anmelden. Welche Daten da zu übermitteln sind, kannst du aus der entsprechenden Webseite auslesen, denn das Formular muss dort ja definiert sein.
Vielleicht reicht auch der Zugriff auf die URL via http://username:passwort@somesite.de/feed.php

Gruß
Sparrow
above
User
Beiträge: 3
Registriert: Dienstag 20. November 2012, 00:07

Danke für die Antwort. Das habe ich auch schon probiert, aber urlopen beschwert sich dann über eine malformed URL oder etwas in der Art (obwohl es im Browser funktioniert hat). Habe jedenfalls jetzt eine funktionierende Möglicheit gefunden, mich mit einem geschützten RSS-Feed zu verbinden und mal eine Methode zusammgeschrieben (die zumindest für mich und für UTF-8-kodierte RSS-Feeds funktioniert):

Code: Alles auswählen

from urllib.request import *
from http.cookiejar import CookieJar

def get_sourcecode(rss_feed_url, username, password):
    password_manager = HTTPPasswordMgrWithDefaultRealm()
    password_manager.add_password(None, rss_feed_url, username, password)

    opener = build_opener(
               HTTPRedirectHandler(),
               HTTPHandler(debuglevel=0),
               HTTPSHandler(debuglevel=0),
               HTTPCookieProcessor(CookieJar()),
               HTTPBasicAuthHandler(password_manager)
             )
    try:
      response = opener.open(rss_feed_url)
      sourcecode = response.read().decode("utf-8")
    except IOError as error:
      sourcecode = str(error)

    return sourcecode


#So ruft man es auf:
url = "https://irgendeineseite.de/feed.php"
sourcecode = get_sourcecode(url, "username", "password")
print(x)
BlackJack

@above: Ich vermute mal das im Benutzernamen und/oder im Passwort Zeichen enthalten waren, die in URLs eine besondere Bedeutung haben, die hätte man dann entsprechend „escapen” müssen. Wenn der Benutzername zum Beispiel eine E-Mail-Adresse ist, dann wäre die URL ja nicht mehr eindeutig: ``http://name@example.org:secret@example.org/feed`` Das müsste man dann so schreiben: ``http://name%40example.org:secret@example.org/feed``.
above
User
Beiträge: 3
Registriert: Dienstag 20. November 2012, 00:07

Habe gerade noch einmal nachgeguckt, es war gar keine Malformed URL, sondern ich bekam eine Exception á la "InvalidURL: non-nummeric port". Er schien mit dem Doppelpunkt hinter dem Usernamen ein Problem zu haben und schien das als Port zu interpretieren. Habe versucht, es mauell zu escapen, so wie du mir es beschrieben hast, und danach auch noch einmal mit urllib.parse.quote(url) und re.escape(url). Hat aber beides dazu geführt, dass urllib.urlopen(url) nicht mehr mit den escapeten URLs umgehen konnte.

Nach etwas Wühlen in der Dokumentation (ich finde die Python-Dokumentation wirklich nicht gut V.V) habe ich dann die Klasse FancyURLopener gefunden, mit der ich solche URLs öffnen kann:

Code: Alles auswählen

from urllib.request import FancyURLopener
url = "https://username:password@somesite.com/feed"
opener = FancyURLopener({})
response = opener.open(url)
print(response.read().decode("utf-8"))
Dennoch danke für den Anreiz :)
lunar

@above Denke über den Einsatz von requests nach.
Antworten