URLからプロトコル+ホスト名を取得する


160

私のDjangoアプリでは、次のrequest.META.get('HTTP_REFERER')ようなURL から取得できるように、プロトコルとともにリファラーからホスト名を取得する必要があります。

私は得るべきです:

私は他の関連する質問を調べて、urlparseについて見つけました、しかしそれはそれ以来トリックをしませんでした

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

回答:


296

urlparse(docs:python2python3)でそれを行うことができるはずです:

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

この答え/ 3番目の例http://www.domain.comにを追加しますが、これは答えでなく質問の欠点であると思います。
SingleNegationElimination 2012年

@TokenMacGuy:ええ、私の悪い...不足していることに気づかなかった/
Gerard

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
Python 3では、urlparseモジュールの名前が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
これは、ドメイン名を取得する方法と書かれた質問に対する正しい答えです。選ばれた解決策は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
Simon Steinberger

1
@SimonSteinberger :-)ハウバウト::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
Python 3の場合、インポートはfrom urllib.parse import urlparseです。
ジェフボーウェン

7

あなたがあなたのURLが有効であると思うなら、これはいつもうまくいくでしょう

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

最後splitは間違っています。分割するスラッシュはもうありません。
CONvid19

2
これは問題にはなりません。スラッシュがなくなると、リストは1つの要素で返されます。したがって、スラッシュの有無に関係なく機能します
ZeroErr0r '13

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

* ヘッダーOriginで使用されますXMLHttpRequest


0

2番目の引数として相対ルート '/'を指定して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.