Dapatkan protokol + nama host dari URL

162

Dalam aplikasi Django saya, saya perlu mendapatkan nama host dari pengarah request.META.get('HTTP_REFERER')bersama dengan protokolnya sehingga dari URL seperti:

Saya harus mendapatkan:

Saya mencari pertanyaan terkait lainnya dan menemukan tentang urlparse, tetapi sejak itu tidak berhasil

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

Jawaban:

297

Anda harus dapat melakukannya dengan 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
sumber
jawaban ini menambahkan sebuah /untuk contoh ketiga http://www.domain.com, tapi saya pikir ini mungkin kelemahan dari pertanyaan, bukan dari jawabannya.
SingleNegationElimination
@TokenMacGuy: ya, salahku ... tidak memperhatikan yang hilang /
Gerard
8
urlparse.urlparse()mengembalikan hasil seperti-nama; Anda bisa menggunakan {uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri)untuk keterbacaan.
jfs
12
Saya tidak berpikir ini adalah solusi yang baik, karena netlocbukan domain: mencoba urlparse.urlparse('http://user:[email protected]:8080')dan menemukan memberikan bagian seperti 'user:pass@'dan':8080'
starrify
22
Modul urlparse diubah namanya menjadi urllib.parse dengan Python 3. Jadi,from urllib.parse import urlparse
SparkAndShine
86

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

Ini adalah versi urlparse yang lebih verbose. Ini mendeteksi domain dan subdomain untuk Anda.

Dari dokumentasi mereka:

>>> 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 adalah namesupuple, jadi mudah untuk mengakses bagian yang Anda inginkan.

>>> ext = tldextract.extract('http://forums.bbc.co.uk')
>>> ext.domain
'bbc'
>>> '.'.join(ext[:2]) # rejoin subdomain and domain
'forums.bbc'
dm03514
sumber
2
Ini adalah jawaban yang benar untuk pertanyaan yang ditulis, bagaimana cara mendapatkan nama DOMAIN. Solusi yang dipilih menyediakan HOSTNAME, yang saya percaya adalah yang paling diinginkan oleh penulis.
Scone
49

Python3 menggunakan 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
sumber
23

Operasi string murni :):

>>> 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'

Itu saja, semuanya.

SebMa
sumber
2
Opsi yang bagus dan sederhana, tetapi gagal dalam beberapa kasus, misalnya foo.bar?haha
Simon Steinberger
1
@SimonSteinberger :-) Bagaimana kalau ini: 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
sumber
2
Untuk Python 3 impornya adalah from urllib.parse import urlparse.
Jeff Bowen
8

jika menurut Anda url Anda valid maka ini akan berfungsi sepanjang waktu

domain = "http://google.com".split("://")[1].split("/")[0] 
ZeroErr0r
sumber
Yang terakhir splitsalah, tidak ada lagi garis miring ke depan untuk dibagi.
CONvid19
2
itu tidak akan menjadi masalah, jika tidak ada lagi garis miring, daftar akan kembali dengan satu elemen. jadi itu akan berfungsi apakah ada garis miring atau tidak
ZeroErr0r
1
Saya mengedit jawaban Anda untuk dapat menghapus suara-turun. Penjelasan yang bagus. Tks.
CONvid19
5

Apakah ada yang salah dengan operasi string murni:

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

Jika Anda lebih suka menambahkan garis miring ditambahkan, rentangkan skrip ini sedikit seperti ini:

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

Itu mungkin bisa sedikit dioptimalkan ...

Simon Steinberger
sumber
7
itu tidak salah, tetapi kami memiliki alat yang sudah melakukan pekerjaan, mari kita tidak menemukan kembali roda;)
Gerard
5

Ini versi yang sedikit ditingkatkan:

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

Keluaran

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

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

Faiz
sumber
IMHO solusi terbaik, karena sederhana dan mempertimbangkan segala macam kasus langka. Terima kasih!
Simon Steinberger
2
tidak sederhana atau ditingkatkan
Corey Goldberg
Ini bukan solusi untuk pertanyaan karena Anda tidak menyediakan protokol (https: // atau http: //)
Alexei Marinichenko
2

Ini agak tumpul, tetapi digunakan urlparsedi kedua arah:

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

("",) * 4bit aneh itu karena urlparse mengharapkan urutan tepat len(urlparse.ParseResult._fields) = 6

SingleNegationElimination
sumber
2

Saya tahu ini pertanyaan lama, tetapi saya juga menjumpainya hari ini. Selesaikan ini dengan satu kalimat:

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

Fungsi perpustakaan standar urllib.parse.urlsplit () adalah semua yang Anda butuhkan. Berikut adalah contoh untuk 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
sumber
1

Itu bisa diselesaikan dengan re.search ()

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
sumber
0

untuk mendapatkan domain / nama host dan Asal *

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

* Origindigunakan dalam XMLHttpRequestheader

cieunteung
sumber
0

Anda cukup menggunakan urljoin dengan root relatif '/' sebagai argumen kedua:

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
sumber
-1

Jika mengandung kurang dari 3 garis miring maka Anda telah mendapatkannya dan jika tidak maka kita dapat menemukan kejadian di antaranya:

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
sumber