Protokoll + Hostname von URL abrufen

160

In meiner Django-App muss ich den Hostnamen vom Referrer request.META.get('HTTP_REFERER')zusammen mit seinem Protokoll abrufen, damit URLs wie:

Ich sollte bekommen:

Ich habe mir andere verwandte Fragen angesehen und etwas über urlparse herausgefunden, aber das hat seitdem nicht mehr funktioniert

>>> urlparse(request.META.get('HTTP_REFERER')).hostname
'docs.google.com'
Gerard
quelle

Antworten:

296

Sie sollten dazu in der Lage sein urlparse(docs: python2 , python3 ):

from urllib.parse import urlparse
# from urlparse import urlparse  # Python 2
parsed_uri = urlparse('http://stackoverflow.com/questions/1234567/blah-blah-blah-blah' )
result = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri)
print(result)

# gives
'http://stackoverflow.com/'
kgr
quelle
diese Antwort fügt eine /das dritte Beispiel http://www.domain.com, aber ich denke , das ist ein Manko der Frage sein könnte, nicht der Antwort.
SingleNegationElimination
@ TokenMacGuy: ya, mein schlechtes ... hat das fehlende /
Gerard
8
urlparse.urlparse()gibt ein benanntes Tupel-ähnliches Ergebnis zurück; Sie könnten {uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri)für die Lesbarkeit verwenden.
JFS
12
Ich denke nicht, dass dies eine gute Lösung ist, da netloces sich nicht um eine Domain handelt: Versuchen Sie urlparse.urlparse('http://user:[email protected]:8080')herauszufinden, dass Teile wie 'user:pass@'and':8080'
starrify
22
Das urlparse-Modul wird in Python 3 in urllib.parse umbenannt. Also,from urllib.parse import urlparse
SparkAndShine
86

https://github.com/john-kurkowski/tldextract

Dies ist eine ausführlichere Version von urlparse. Es erkennt Domains und Subdomains für Sie.

Aus ihrer Dokumentation:

>>> import tldextract
>>> tldextract.extract('http://forums.news.cnn.com/')
ExtractResult(subdomain='forums.news', domain='cnn', suffix='com')
>>> tldextract.extract('http://forums.bbc.co.uk/') # United Kingdom
ExtractResult(subdomain='forums', domain='bbc', suffix='co.uk')
>>> tldextract.extract('http://www.worldbank.org.kg/') # Kyrgyzstan
ExtractResult(subdomain='www', domain='worldbank', suffix='org.kg')

ExtractResult ist ein benanntes Tupel, daher ist es einfach, auf die gewünschten Teile zuzugreifen.

>>> ext = tldextract.extract('http://forums.bbc.co.uk')
>>> ext.domain
'bbc'
>>> '.'.join(ext[:2]) # rejoin subdomain and domain
'forums.bbc'
dm03514
quelle
2
Dies ist die richtige Antwort auf die geschriebene Frage, wie man den DOMAIN-Namen erhält. Die gewählte Lösung liefert den HOSTNAME, von dem ich glaube, dass er der Autor überhaupt wollte.
Scone
49

Python3 mit urlsplit :

from urllib.parse import urlsplit
url = "http://stackoverflow.com/questions/9626535/get-domain-name-from-url"
base_url = "{0.scheme}://{0.netloc}/".format(urlsplit(url))
print(base_url)
# http://stackoverflow.com/
Marc SJ
quelle
23

Reine String-Operationen :):

>>> url = "http://stackoverflow.com/questions/9626535/get-domain-name-from-url"
>>> url.split("//")[-1].split("/")[0].split('?')[0]
'stackoverflow.com'
>>> url = "stackoverflow.com/questions/9626535/get-domain-name-from-url"
>>> url.split("//")[-1].split("/")[0].split('?')[0]
'stackoverflow.com'
>>> url = "http://foo.bar?haha/whatever"
>>> url.split("//")[-1].split("/")[0].split('?')[0]
'foo.bar'

Das war's Leute.

SebMa
quelle
2
Gute und einfache Option, schlägt aber in einigen Fällen fehl, z. B. foo.bar?haha
Simon Steinberger
1
@ SimonSteinberger :-) Wie wäre es damit : url.split("//")[-1].split("/")[0].split('?')[0]:-))
SebMa
22
>>> import urlparse
>>> url = 'http://stackoverflow.com/questions/1234567/blah-blah-blah-blah'
>>> urlparse.urljoin(url, '/')
'http://stackoverflow.com/'
png
quelle
2
Für Python 3 ist der Import from urllib.parse import urlparse.
Jeff Bowen
7

Wenn Sie glauben, dass Ihre URL gültig ist, funktioniert dies die ganze Zeit

domain = "http://google.com".split("://")[1].split("/")[0] 
ZeroErr0r
quelle
Letzteres splitist falsch, es sind keine Schrägstriche mehr zu teilen.
CONvid19
2
Es ist kein Problem, wenn dann keine Schrägstriche mehr vorhanden sind, wird die Liste mit einem Element zurückgegeben. so wird es funktionieren, ob es einen Schrägstrich gibt oder nicht
ZeroErr0r
1
Ich habe Ihre Antwort bearbeitet, um die Abwahl entfernen zu können. Schöne Erklärung. Tks.
CONvid19
5

Stimmt etwas mit reinen String-Operationen nicht:

url = 'http://stackoverflow.com/questions/9626535/get-domain-name-from-url'
parts = url.split('//', 1)
print parts[0]+'//'+parts[1].split('/', 1)[0]
>>> http://stackoverflow.com

Wenn Sie es vorziehen, einen abschließenden Schrägstrich anhängen zu lassen, erweitern Sie dieses Skript folgendermaßen:

parts = url.split('//', 1)
base = parts[0]+'//'+parts[1].split('/', 1)[0]
print base + (len(url) > len(base) and url[len(base)]=='/'and'/' or '')

Das kann wohl ein bisschen optimiert werden ...

Simon Steinberger
quelle
7
es ist nicht falsch, aber wir haben ein Werkzeug, das bereits die Arbeit erledigt, lasst uns das Rad nicht neu erfinden;)
Gerard
5

Hier ist eine leicht verbesserte Version:

urls = [
    "http://stackoverflow.com:8080/some/folder?test=/questions/9626535/get-domain-name-from-url",
    "Stackoverflow.com:8080/some/folder?test=/questions/9626535/get-domain-name-from-url",
    "http://stackoverflow.com/some/folder?test=/questions/9626535/get-domain-name-from-url",
    "https://StackOverflow.com:8080?test=/questions/9626535/get-domain-name-from-url",
    "stackoverflow.com?test=questions&v=get-domain-name-from-url"]
for url in urls:
    spltAr = url.split("://");
    i = (0,1)[len(spltAr)>1];
    dm = spltAr[i].split("?")[0].split('/')[0].split(':')[0].lower();
    print dm

Ausgabe

stackoverflow.com
stackoverflow.com
stackoverflow.com
stackoverflow.com
stackoverflow.com

Geige: https://pyfiddle.io/fiddle/23e4976e-88d2-4757-993e-532aa41b7bf0/?i=true

Faiz
quelle
IMHO die beste Lösung, weil einfach und es berücksichtigt alle Arten von seltenen Fällen. Vielen Dank!
Simon Steinberger
2
weder einfach noch verbessert
Corey Goldberg
Dies ist keine Lösung für die Frage, da Sie kein Protokoll (https: // oder http: //)
angeben
2

Dies ist etwas stumpf, wird aber urlparsein beide Richtungen verwendet:

import urlparse
def uri2schemehostname(uri):
    urlparse.urlunparse(urlparse.urlparse(uri)[:2] + ("",) * 4)

("",) * 4Dieses ungerade Bit ist, weil urlparse eine Folge von genau len(urlparse.ParseResult._fields) = 6 erwartet

SingleNegationElimination
quelle
2

Ich weiß, dass es eine alte Frage ist, aber auch ich bin heute darauf gestoßen. Dies wurde mit einem Einzeiler gelöst:

import re
result = re.sub(r'(.*://)?([^/?]+).*', '\g<1>\g<2>', url)
Orix Au Yeung
quelle
2

Die Standardbibliotheksfunktion urllib.parse.urlsplit () ist alles, was Sie brauchen. Hier ist ein Beispiel für Python3:

>>> import urllib.parse
>>> o = urllib.parse.urlsplit('https://user:[email protected]:8080/dir/page.html?q1=test&q2=a2#anchor1')
>>> o.scheme
'https'
>>> o.netloc
'user:[email protected]:8080'
>>> o.hostname
'www.example.com'
>>> o.port
8080
>>> o.path
'/dir/page.html'
>>> o.query
'q1=test&q2=a2'
>>> o.fragment
'anchor1'
>>> o.username
'user'
>>> o.password
'pass'
Famzah
quelle
1

Es könnte durch re.search () gelöst werden

import re
url = 'https://docs.google.com/spreadsheet/ccc?key=blah-blah-blah-blah#gid=1'
result = re.search(r'^http[s]*:\/\/[\w\.]*', url).group()
print(result)

#result
'https://docs.google.com'
Kiwi
quelle
0

um Domain / Hostname und Origin zu erhalten *

url = '/programming/9626535/get-protocol-host-name-from-url'
hostname = url.split('/')[2] # stackoverflow.com
origin = '/'.join(url.split('/')[:3]) # https://stackoverflow.com

* Originwird in XMLHttpRequestHeadern verwendet

cieunteung
quelle
0

Sie können einfach urljoin mit der relativen Wurzel '/' als zweites Argument verwenden:

try:
    from urlparse import urljoin  # Python2
except ImportError:
    from urllib.parse import urljoin  # Python3


url = '/programming/9626535/get-protocol-host-name-from-url'

root_url = urljoin(url, '/')
Mirko
quelle
-1

Wenn es weniger als 3 Schrägstriche enthält, haben Sie es und wenn nicht, können wir das Vorkommen dazwischen finden:

import re

link = http://forum.unisoftdev.com/something

slash_count = len(re.findall("/", link))
print slash_count # output: 3

if slash_count > 2:
   regex = r'\:\/\/(.*?)\/'
   pattern  = re.compile(regex)
   path = re.findall(pattern, url)

   print path
Juraj
quelle