从URL获取协议+主机名

Ger*_*ard 144 python django

在我的Django应用程序中,我需要从referrer中获取主机名request.META.get('HTTP_REFERER')及其协议,以便从以下URL中获取:

我应该得到:

我查看了其他相关的问题,发现了关于urlparse,但是从那以后就没办法了

>>> urlparse(request.META.get('HTTP_REFERER')).hostname
'docs.google.com'
Run Code Online (Sandbox Code Playgroud)

kgr*_*kgr 261

您应该可以使用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/'
Run Code Online (Sandbox Code Playgroud)

  • urlparse模块在Python 3中重命名为urllib.parse.因此,`来自urllib.parse import urlparse` (21认同)
  • 我不认为这是一个很好的解决方案,因为`netloc`不是域:尝试`urlparse.urlparse('http:// user:pass@example.com:8080')`并找到它给出像''这样的部分user:传递@'和`':8080' (11认同)
  • `urlparse.urlparse()`返回一个类似于类似结果的结果; 为了便于阅读,你可以使用`{uri.scheme}:// {uri.netloc} /'.format(uri = parsed_uri)`. (7认同)

dm0*_*514 78

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')
Run Code Online (Sandbox Code Playgroud)

ExtractResult 是一个namedtuple,所以访问你想要的部分很简单.

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

  • 这是所写问题(如何获得DOMAIN名称)的正确答案。选择的解决方案提供了HOSTNAME,我相信这是作者首先想要的。 (2认同)

小智 42

Python3使用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/
Run Code Online (Sandbox Code Playgroud)


Seb*_*bMa 22

纯字符串操作:):

>>> 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'
Run Code Online (Sandbox Code Playgroud)

总而言之,伙计们.

  • 好的简单的选项,但是在某些情况下会失败,例如https://foo.bar?haha (2认同)

png*_*png 21

>>> import urlparse
>>> url = 'http://stackoverflow.com/questions/1234567/blah-blah-blah-blah'
>>> urlparse.urljoin(url, '/')
'http://stackoverflow.com/'
Run Code Online (Sandbox Code Playgroud)

  • 对于 Python 3,导入是`from urllib.parse import urlparse`。 (3认同)
  • 这个论点看起来并不直观,但它作为一个非常简单的本机解决方案非常有效 (2认同)

fam*_*zah 8

标准库函数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'
Run Code Online (Sandbox Code Playgroud)


Jee*_*eva 7

如果您认为自己的网址有效,那么它将一直有效

domain = "http://google.com".split("://")[1].split("/")[0] 
Run Code Online (Sandbox Code Playgroud)

  • 这不会有问题,如果没有更多斜杠,则列表将返回一个元素。所以不管有没有斜线它都会工作 (2认同)

Sim*_*ger 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
Run Code Online (Sandbox Code Playgroud)

如果您更喜欢附加斜杠,请像这样扩展此脚本:

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

这可能可以优化一点......

  • 这没有错,但我们有一个已经可以完成工作的工具,让我们不要重新发明轮子;) (8认同)

Fai*_*aiz 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
Run Code Online (Sandbox Code Playgroud)

产量

stackoverflow.com
stackoverflow.com
stackoverflow.com
stackoverflow.com
stackoverflow.com
Run Code Online (Sandbox Code Playgroud)

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

  • 既不简单也不改进 (2认同)