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'

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

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:pass@example.com: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'

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/

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.


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

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] 

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


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


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


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)

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:pass@www.example.com:8080/dir/page.html?q1=test&q2=a2#anchor1')
>>> o.scheme
'https'
>>> o.netloc
'user:pass@www.example.com: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'

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'

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


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, '/')

-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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.