URL에서 프로토콜 + 호스트 이름 가져 오기


162

Django 앱에서 다음 request.META.get('HTTP_REFERER')과 같은 URL에서 프로토콜과 함께 리퍼러에서 호스트 이름을 가져와야 합니다.

나는 얻어야한다 :

다른 관련 질문을 살펴보고 urlparse에 대해 찾았지만 그 이후로는 속임수가 없었습니다.

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

답변:


297

당신은 그것을 할 수 있어야합니다 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/'

이 답변 은 세 번째 예에 a 를 추가 하지만 이것이 답변 이 아닌 질문의 단점 일 수 있다고 생각합니다. /http://www.domain.com
SingleNegationElimination 1

@TokenMacGuy : 나중에, 내 나쁜 ... 누락을 통지하지 않았다 /
제라드

8
urlparse.urlparse()명명 된 튜플과 같은 결과를 반환합니다. {uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri)가독성을 위해 사용할 수 있습니다 .
jfs

12
나는,이 좋은 솔루션입니다 생각하지 않습니다 netloc시도 : 도메인이 아닌 urlparse.urlparse('http://user:pass@example.com:8080')과 같이 부품을 제공 발견 'user:pass@'하고':8080'
starrify

22
urlparse 모듈은 파이썬 3에서 urllib.parse로 이름이 변경되었습니다.from urllib.parse import urlparse
SparkAndShine

86

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

이것은 더 장황한 urlparse 버전입니다. 도메인과 하위 도메인을 감지합니다.

그들의 문서에서 :

>>> 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 명명 된 튜플이므로 원하는 부분에 간단하게 액세스 할 수 있습니다.

>>> ext = tldextract.extract('http://forums.bbc.co.uk')
>>> ext.domain
'bbc'
>>> '.'.join(ext[:2]) # rejoin subdomain and domain
'forums.bbc'

2
이것은 DOMAIN 이름을 얻는 방법으로 쓰여진 질문에 대한 정답입니다. 선택한 솔루션은 HOSTNAME을 제공합니다. HOSTNAME은 저자가 처음에 원했던 것입니다.
스콘

49

urlsplit을 사용하는 Python3 :

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

순수한 문자열 연산 :) :

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

그게 다야 사람들.


2
좋은 간단한 옵션,하지만 어떤 경우에는 실패, 예를 들어 foo.bar?haha
사이먼 스타 인 버거

1
@SimonSteinberger :-) How'bout this : 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
파이썬 3의 경우 수입은 from urllib.parse import urlparse입니다.
Jeff Bowen

8

URL이 유효하다고 생각되면 항상 작동합니다.

domain = "http://google.com".split("://")[1].split("/")[0] 

마지막 split은 잘못되었습니다. 더 이상 슬래시를 나눌 필요가 없습니다.
CONvid19

2
더 이상 슬래시가 없으면 하나의 요소와 함께 목록이 반환됩니다. 따라서 슬래시가 있는지 여부에 관계없이 작동합니다
ZeroErr0r

1
다운 투표를 제거 할 수 있도록 귀하의 답변을 편집했습니다. 좋은 설명입니다. Tks.
CONvid19

5

순수한 문자열 연산에 문제가 있습니까?

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

후행 슬래시를 추가하려면이 스크립트를 다음과 같이 확장하십시오.

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

아마 조금 최적화 될 수 있습니다 ...


7
틀린 것은 아니지만 우리는 이미 작업을 수행하는 도구를 얻었습니다. 바퀴를 재발 명하지 마십시오.)
Gerard

5

다음은 약간 개선 된 버전입니다.

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

산출

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

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


간단하고 모든 종류의 드문 경우를 고려하기 때문에 IMHO가 최고의 솔루션입니다. 감사!
Simon Steinberger

2
단순하거나 개선되지 않음
Corey Goldberg

프로토콜 (https : // 또는 http : //)을 제공하지 않기 때문에 이것은 질문에 대한 해결책이 아닙니다
Alexei Marinichenko

2

이것은 약간 애매하지만 urlparse양방향으로 사용합니다.

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

그 이상한 ("",) * 4비트는 urlparse가 정확히 len(urlparse.ParseResult._fields) = 6 의 시퀀스를 기대하기 때문입니다


2

나는 그것이 오래된 질문이라는 것을 알고 있지만 오늘도 그것을 만났습니다. 하나의 라이너로 이것을 해결했습니다.

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

2

표준 라이브러리 함수 urllib.parse.urlsplit () 만 있으면됩니다. 다음은 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

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

도메인 / 호스트 이름 및 원본을 얻으려면 *

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

* OriginXMLHttpRequest헤더에 사용됩니다


0

상대 루트 '/'와 함께 urljoin을 두 번째 인수로 사용할 수 있습니다.

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

슬래시가 3 개 미만인 경우 슬래시가 있고 그렇지 않으면 그 사이에 발생을 찾을 수 있습니다.

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.