Im Internetzeitalter stellt die URL (Uniform Resource Locator) die grundlegende Adresse dar, die den Standort von Informationen angibt. In verschiedenen Bereichen wie Webentwicklung und Datenanalyse muss man häufig mit URLs arbeiten, und manchmal ist es notwendig, nur bestimmte Teile der URL (z. B. den Domainnamen, den Pfad, die Abfrageparameter) zu extrahieren. Hierbei wird die Funktion urlparse() aus dem urllib.parse-Modul von Python als kraftvolles Werkzeug verwendet.

In diesem Artikel werden wir die grundlegende Verwendung der urlparse()-Funktion, die Bedeutung und Anwendungsfälle der häufig verwendeten .netloc-Eigenschaft sowie die verschiedenen Eigenschaften des ParseResult-Objekts, das von urlparse() zurückgegeben wird, im Detail betrachten.


1. Was ist urlparse()?



urlparse() ist eine Funktion, die eine URL-Zeichenfolge gemäß den Standards RFC 1738 (Universal Resource Locators in WWW) und RFC 3986 (Uniform Resource Identifier (URI): Generic Syntax) in mehrere Komponenten zerlegt. Jede dieser zerlegten Komponenten wird in einem speziellen Objekt mit dem Namen ParseResult verpackt und zurückgegeben.

Grundlegende Verwendung

Die Funktion urlparse() wird importiert und verwendet durch das urllib.parse-Modul.

from urllib.parse import urlparse

url = 'https://user:pass@www.example.com:8080/path/to/resource?name=Alice&age=30#section1'
parsed_url = urlparse(url)

print(parsed_url)
# Ausgabe: ParseResult(scheme='https', netloc='user:pass@www.example.com:8080', path='/path/to/resource', params='', query='name=Alice&age=30', fragment='section1')

Das parsed_url-Objekt kann sowohl über Indizes wie ein Tupel als auch über benannte Eigenschaften (named attribute) angesprochen werden. Letzteres ist wesentlich lesbarer.


2. Wichtige Eigenschaften des ParseResult-Objekts

Das von urlparse() zurückgegebene ParseResult-Objekt besitzt folgende Eigenschaften:

scheme

  • Bedeutung: Repräsentiert den Protokollteil der URL. (http, https, ftp, mailto usw.)

  • Beispiel: 'https'

netloc (Netzwerkstandort)

  • Bedeutung: Teil, der den Hostnamen (Domain), die Portnummer und optional die Benutzeranmeldeinformationen (user:pass@) enthält.

  • Beispiel: 'user:pass@www.example.com:8080'

  • Verwendung: Nützlich, um nur die Domain eines bestimmten Webdienstes zu extrahieren oder die Portnummer zu überprüfen, um sie für die Netzwerkverbindung zu nutzen. Dies wird später näher behandelt.

path

  • Bedeutung: Repräsentiert den spezifischen Ressourcenteil auf dem Webserver.

  • Beispiel: '/path/to/resource'

params (Pfadparameter)

  • Bedeutung: Pfadparameter, die durch Semikolons (;) getrennt sind. Diese sind in der RFC definiert, werden jedoch in modernen Webanwendungen kaum genutzt, meist wird die Abfrage (query) verwendet.

  • Beispiel: ';sessionid=xyz' (selten verwendet)

query

  • Bedeutung: Die Abfragestruktur, die nach dem Fragezeichen (?) kommt. Wird verwendet, um Daten im Schlüssel-Wert-Paar-Format an den Server zu übermitteln.

  • Beispiel: 'name=Alice&age=30'

  • Verwendung: In Kombination mit der Funktion urllib.parse.parse_qs() kann sie leicht in ein Dictionary umgewandelt werden.

from urllib.parse import parse_qs
query_params = parse_qs(parsed_url.query)
print(query_params)
# Ausgabe: {'name': ['Alice'], 'age': ['30']}

fragment

  • Bedeutung: Der Fragmentbezeichner, der nach dem Hash-Zeichen (#) kommt. Wird hauptsächlich verwendet, um zu einem bestimmten Abschnitt auf einer Webseite zu navigieren und wird nicht an den Server gesendet, sondern nur vom Browser verarbeitet.

  • Beispiel: 'section1'


3. Tiefenanalyse der .netloc-Eigenschaft



.netloc ist eine besonders wichtige Eigenschaft unter den Ergebnissen von urlparse(). netloc ist die Abkürzung für Netzwerkstandort (Network Location) und enthält die Schlüsselinformationen zur Adresse des Webservers in der URL.

netloc - Elementebene

netloc kann aus folgenden Elementen bestehen:

  • Benutzerinformationen (Userinfo): Kann den Benutzernamen und das Passwort im Format user:password@ enthalten. Aufgrund von Sicherheitsüberlegungen wird dies in allgemeinen Web-URLs kaum verwendet, ist aber bei anderen Protokollen wie FTP zu finden.

  • Host: Der Domainname (www.example.com) oder die IP-Adresse (192.168.1.1).

  • Port: Die Portnummer, die an : anschließt. Wenn der Standardport von HTTP (80) oder HTTPS (443) verwendet wird, kann die Portnummer im netloc weggelassen werden.

Beispiel:

URL netloc Ergebnis Beschreibung
https://www.example.com www.example.com Nur Domain enthalten (HTTPS Standardport 443 weggelassen)
http://myhost:8000/app myhost:8000 Enthält Host und Port
ftp://user:pass@ftp.example.org user:pass@ftp.example.org Benutzerinformationen und Host enthalten

Gründe und Szenarien zur Nutzung von .netloc

  1. Extraktion und Validierung von Domains:

    • Durch Überprüfung, von welcher Website eine Anfrage stammt, können Sicherheitsrichtlinien angewendet oder nur bestimmte Domains erlaubt werden, indem die Domain-Teile leicht aus netloc extrahiert werden.

    • Mit der Eigenschaft parsed_url.hostname kann nur der Hostname ohne die Portnummer abgerufen werden.

url = 'https://www.example.com:8080/path'
parsed = urlparse(url)
print(parsed.netloc)    # 'www.example.com:8080'
print(parsed.hostname)  # 'www.example.com'
print(parsed.port)      # 8080 (int)
  1. URL-Rekonstruktion oder -Änderung:

    • Das von urlparse() zerlegte ParseResult-Objekt ist unveränderlich (immutable), jedoch kann mit der .replace()-Methode ein neues ParseResult-Objekt erstellt werden, bei dem nur bestimmte Eigenschaften geändert werden. Dieses geänderte Objekt kann dann an die Funktion urlunparse() übergeben werden, um eine neue URL leicht zu rekonstruieren.

    • Zum Beispiel kann bei der Implementierung einer Weiterleitung auf eine bestimmte Domain die URL erstellt werden, indem nur netloc geändert wird.

from urllib.parse import urlparse, urlunparse

original_url = 'https://old.example.com/data'
parsed_original = urlparse(original_url)

# Erstelle neue URL durch Ändern nur der Domain
new_netloc = 'new.example.com'
modified_parsed = parsed_original._replace(netloc=new_netloc)
new_url = urlunparse(modified_parsed)

print(new_url) # Ausgabe: https://new.example.com/data
  1. Vergleich der URL-Identität (auf Basis von Domain/Port):

    • Wenn überprüft werden muss, ob zwei URLs denselben Server ansprechen, ist der Vergleich der netloc-Eigenschaft nützlich.
url1 = 'https://api.myapp.com/v1/users'
url2 = 'https://api.myapp.com:443/v2/products' # 443 ist der Standardport für HTTPS
url3 = 'https://oldapi.myapp.com/v1/users'

parsed1 = urlparse(url1)
parsed2 = urlparse(url2)
parsed3 = urlparse(url3)

print(parsed1.netloc == parsed2.netloc) # True (Standardports können weggelassen und gleich behandelt werden)
print(parsed1.hostname == parsed2.hostname) # True
print(parsed1.netloc == parsed3.netloc) # False

4. Unterschiede zwischen urlparse() und urlsplit()

Im urllib.parse-Modul gibt es auch die Funktion urlsplit(), die urlparse() sehr ähnlich ist. Der Hauptunterschied zwischen den beiden Funktionen besteht darin, wie sie die params-Eigenschaft behandeln.

  • urlparse(): Trennt die params-Eigenschaft separat.

  • urlsplit(): Enthält die params-Eigenschaft im path-Teil und gibt anstelle des ParseResult ein SplitResult-Objekt zurück, das keine params-Eigenschaft hat.

Da params in der modernen Webentwicklung kaum verwendet wird, ist es in vielen Fällen akzeptabel, urlsplit() zu verwenden. Allerdings bietet urlparse() eine allgemeinere und vollständigere Trennung.


Fazit: Ein unverzichtbares Werkzeug zur URL-Analyse

Die Funktion urlparse() von Python ist ein leistungsstarkes Werkzeug, das komplexe URL-Zeichenfolgen systematisch zerlegt und es ermöglicht, nur die benötigten Teile zu extrahieren und zu verwenden. Insbesondere die .netloc-Eigenschaft stellt die wesentlichen Informationen zum Host und zur Portnummer der URL bereit und ist von großem Nutzen bei der Verarbeitung domainbasierter Logik oder bei der Rekonstruktion von URLs.

Für alle Python-Entwickler, die mit URLs zu tun haben, sei es beim Web-Scraping, bei der Verarbeitung von API-Anfragen oder bei der Sicherheitsüberprüfung, ist urlparse() ein absolutes Muss. Nutzen Sie diese Funktion, um URL-Daten effektiver zu steuern und zu nutzen.

urlparse Konzeptdiagramm