web-dev-qa-db-ja.com

URLからドメイン名を取得する方法

URL文字列からドメイン名を取得するにはどうすればよいですか?

例:

+----------------------+------------+
| input                | output     |
+----------------------+------------+
| www.google.com       | google     |
| www.mail.yahoo.com   | mail.yahoo |
| www.mail.yahoo.co.in | mail.yahoo |
| www.abc.au.uk        | abc        |
+----------------------+------------+

関連:

49
Chinmay

私はかつて働いていた会社のためにそのような正規表現を書く必要がありました。解決策はこれでした:

  • 利用可能なすべての ccTLD および gTLD のリストを取得します。最初の目的地は [〜#〜] iana [〜#〜] です。 Mozillaのリストは一見素晴らしく見えますが、たとえばac.ukがないため、実際には使用できません。
  • 以下の例のようにリストに参加します。 警告:順序は重要です! org.ukukの後に表示される場合、example.org.ukは、exampleの代わりにorgと一致します。

正規表現の例:

.*([^\.]+)(com|net|org|info|coop|int|co\.uk|org\.uk|ac\.uk|uk|__and so on__)$

これは非常にうまく機能し、de.comや友人などの奇妙で非公式のトップレベルにもマッチしました。

利点:

  • 正規表現が最適に注文されている場合、非常に高速

もちろん、このソリューションの欠点は次のとおりです。

  • CcTLDが変更または追加された場合、手動で更新する必要がある手書きの正規表現。退屈な仕事!
  • 非常に大きな正規表現なので、読みにくい。
40
pi.
/^(?:www\.)?(.*?)\.(?:com|au\.uk|co\.in)$/
12
jfs

ドメイン名を正確に抽出することは、主にドメイン拡張子に2つの部分(.com.auや.co.ukなど)が含まれ、サブドメイン(プレフィックス)がある場合とない場合があるため、非常に注意が必要です。すべてのドメイン拡張子をリストすることは、これらが何百もあるためオプションではありません。たとえば、EuroDNS.comには800を超えるドメイン名拡張子がリストされています。

したがって、「parse_url()」とドメイン拡張に関するいくつかの観察を使用して、URLコンポーネントとドメイン名を正確に抽出する短いphp関数を作成しました。機能は次のとおりです。

function parse_url_all($url){
    $url = substr($url,0,4)=='http'? $url: 'http://'.$url;
    $d = parse_url($url);
    $tmp = explode('.',$d['Host']);
    $n = count($tmp);
    if ($n>=2){
        if ($n==4 || ($n==3 && strlen($tmp[($n-2)])<=3)){
            $d['domain'] = $tmp[($n-3)].".".$tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-3)];
        } else {
            $d['domain'] = $tmp[($n-2)].".".$tmp[($n-1)];
            $d['domainX'] = $tmp[($n-2)];
        }
    }
    return $d;
}

この単純な関数は、ほとんどすべての場合に機能します。いくつかの例外がありますが、これらは非常にまれです。

この機能を実証/テストするには、次を使用できます。

$urls = array('www.test.com', 'test.com', 'cp.test.com' .....);
echo "<div style='overflow-x:auto;'>";
echo "<table>";
echo "<tr><th>URL</th><th>Host</th><th>Domain</th><th>Domain X</th></tr>";
foreach ($urls as $url) {
    $info = parse_url_all($url);
    echo "<tr><td>".$url."</td><td>".$info['Host'].
    "</td><td>".$info['domain']."</td><td>".$info['domainX']."</td></tr>";
}
echo "</table></div>";

リストされたURLの出力は次のようになります。

enter image description here

ご覧のとおり、ドメイン名と拡張子のないドメイン名は、関数に表示されるURLが何であれ一貫して抽出されます。

これが役立つことを願っています。

9
Clinton

ライブラリは知りませんが、ドメイン名の文字列操作は簡単です。

難しいのは、名前が第2レベルか第3レベルかを知ることです。このためには、管理するデータファイルが必要です(たとえば、.ukは常に第3レベルではなく、一部の組織(たとえば、bl.uk、jet.uk)は第2レベルに存在します)。

Mozillaの Firefoxのソース にはそのようなデータファイルがあります。Mozillaのライセンスを確認して、再利用できるかどうかを確認してください。

4
Richard

2つの方法があります

分割を使用

次に、その文字列を解析するだけです

var domain;
//find & remove protocol (http, ftp, etc.) and get domain
if (url.indexOf('://') > -1) {
    domain = url.split('/')[2];
} if (url.indexOf('//') === 0) {
    domain = url.split('/')[2];
} else {
    domain = url.split('/')[0];
}

//find & remove port number
domain = domain.split(':')[0];

正規表現を使用

 var r = /:\/\/(.[^/]+)/;
 "http://stackoverflow.com/questions/5343288/get-url".match(r)[1] 
 => stackoverflow.com

お役に立てれば

4
Fizer Khan
import urlparse

GENERIC_TLDS = [
    'aero', 'asia', 'biz', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 
    'mil', 'mobi', 'museum', 'name', 'net', 'org', 'pro', 'tel', 'travel', 'cat'
    ]

def get_domain(url):
    hostname = urlparse.urlparse(url.lower()).netloc
    if hostname == '':
        # Force the recognition as a full URL
        hostname = urlparse.urlparse('http://' + uri).netloc

    # Remove the 'user:passw', 'www.' and ':port' parts
    hostname = hostname.split('@')[-1].split(':')[0].lstrip('www.').split('.')

    num_parts = len(hostname)
    if (num_parts < 3) or (len(hostname[-1]) > 2):
        return '.'.join(hostname[:-1])
    if len(hostname[-2]) > 2 and hostname[-2] not in GENERIC_TLDS:
        return '.'.join(hostname[:-1])
    if num_parts >= 3:
        return '.'.join(hostname[:-2])

このコードはすべてのURLで機能することを保証するものではなく、文法的には正しいが「example.uk」のような無効なURLをフィルタリングしません。

しかし、ほとんどの場合、それは仕事をします。

3

http://www.db.de/ または http://bbc.co.uk/のような多くのケースが存在するため、TLDリストを使用して比較することはできません。 ドメインdb.de(正しい)およびco.uk(間違った)として正規表現によって解釈されます。

しかし、それでもリストにSLDが含まれていない場合は成功しません。 http://big.uk.com/http://www.uk.com/ のようなURLは両方ともuk.com(最初のドメインはbig.uk.comです)。

そのため、すべてのブラウザーはMozillaのパブリックサフィックスリストを使用します。

https://en.wikipedia.org/wiki/Public_Suffix_List

次のURLからインポートすることで、コードで使用できます。

http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1

ドメイン名を抽出するためだけに私の機能を拡張してください。正規表現を使用せず、高速です。

http://www.programmierer-forum.de/domainnamen-ermitteln-t244185.htm#3471878

2
mgutt

基本的に、あなたが望むのは:

google.com        -> google.com    -> google
www.google.com    -> google.com    -> google
google.co.uk      -> google.co.uk  -> google
www.google.co.uk  -> google.co.uk  -> google
www.google.org    -> google.org    -> google
www.google.org.uk -> google.org.uk -> google

オプション:

www.google.com     -> google.com    -> www.google
images.google.com  -> google.com    -> images.google
mail.yahoo.co.uk   -> yahoo.co.uk   -> mail.yahoo
mail.yahoo.com     -> yahoo.com     -> mail.yahoo
www.mail.yahoo.com -> yahoo.com     -> mail.yahoo

名前の最後から2番目の部分を見るだけでドメインの99%が適切に一致するため、常に変化する正規表現を作成する必要はありません。

(co|com|gov|net|org)

これらのいずれかである場合、3つのドットを一致させる必要があります。それ以外の場合は2.です。さて、私の正規表現ウィザードは他のSO'erのものとは一致しないので、これを達成するために私が見つけた最良の方法は、すでにパスを削除したと仮定して、いくつかのコードを使用することです:

 my @d=split /\./,$domain;                # split the domain part into an array
 $c=@d;                                   # count how many parts
 $dest=$d[$c-2].'.'.$d[$c-1];             # use the last 2 parts
 if ($d[$c-2]=~m/(co|com|gov|net|org)/) { # is the second-last part one of these?
   $dest=$d[$c-3].'.'.$dest;              # if so, add a third part
 };
 print $dest;                             # show it

あなたの質問に従って、名前を取得するには:

 my @d=split /\./,$domain;                # split the domain part into an array
 $c=@d;                                   # count how many parts
 if ($d[$c-2]=~m/(co|com|gov|net|org)/) { # is the second-last part one of these?
   $dest=$d[$c-3];                        # if so, give the third last
   $dest=$d[$c-4].'.'.$dest if ($c>3);    # optional bit
 } else {
   $dest=$d[$c-2];                        # else the second last
   $dest=$d[$c-3].'.'.$dest if ($c>2);    # optional bit 
 };
 print $dest;                             # show it

このアプローチは、メンテナンスが不要なため気に入っています。実際に正当なドメインであることを検証する場合を除き、ログファイルを処理するためにこれを使用する可能性が高く、無効なドメインはそもそもその場所を見つけられないため、それは無意味です。

Bozo.za.netやbozo.au.ukなどの「非公式」サブドメインと一致させたい場合、bozo.msf.ruは正規表現に(za | au | msf)を追加するだけです。

私は誰かが正規表現だけを使用してこのすべてを行うのを見てみたい、それは可能だと確信しています。

2
dagelf

/[^w{3}\.]([a-zA-Z0-9]([a-zA-Z0-9\-]{0,65}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}/gim

このjavascript正規表現の使用は、ドメインをそのまま保持しながら、wwwとそれに続くドットを無視します。また、wwwとcc tldが正しく一致しない

1
stancoffyn

この(。)(。*?)(。)を使用して、リーディングポイントとエンドポイントを抽出します。簡単ですね。

0
pabben
  1. これはどのように

    =((?:(?:(?:http)s?:)?\/\/)?(?:(?:[a-zA-Z0-9]+)\.?)*(?:(?:[a-zA-Z0-9]+))\.[a-zA-Z0-9]{2,3})(パターンの最後に「\ /」を追加することもできます

  2. パラメータとして渡されたURLを削除することが目的の場合、次のように最初の文字として等号を追加できます。

    =((?:(?:( ?: http)s?:)?//)?(?:(?:[a-zA-Z0-9] +)。?)*(?:(?:[ a-zA-Z0-9] +))。[a-zA-Z0-9] {2,3} /)

    そして「/」に置き換えます

この例の目標は、表示される形式に関係なく、ドメイン名を削除することです(つまり、xss攻撃を回避するために、URLパラメータにドメイン名が含まれないようにします)。

0
Chaim Klar

削除できるドメインプレフィックスとサフィックスのリストが必要です。例えば:

プレフィックス:

  • www.

接尾辞:

  • .com
  • .co.in
  • .au.uk
0
Gumbo

特定の目的のために、私は昨日このクイックPython関数を実行しました。URLからドメインを返します。高速で、入力ファイルをリストするものを必要としません。しかし、すべてのケースがありますが、単純なテキストマイニングスクリプトに必要な仕事を本当に果たします。

出力は次のようになります。

http://www.google.co.uk => google.co.uk
http://24.media.tumblr.com/tumblr_m04s34rqh567ij78k_250.gif => tumblr.com

def getDomain(url):    
        parts = re.split("\/", url)
        match = re.match("([\w\-]+\.)*([\w\-]+\.\w{2,6}$)", parts[2]) 
        if match != None:
            if re.search("\.uk", parts[2]): 
                match = re.match("([\w\-]+\.)*([\w\-]+\.[\w\-]+\.\w{2,6}$)", parts[2])
            return match.group(2)
        else: return ''  

かなりうまくいくようです。
ただし、出力のドメイン拡張子を削除するには、希望どおりに変更する必要があります。

0
binnie

私は質問が正規表現のソリューションを求めていることを知っていますが、すべての試みですべてをカバーすることはできません

このメソッドをPython)で記述することにしました。これは、サブドメイン(www.mydomain.co.uk)を持ち、www.mail.yahoo.comのような複数レベルのサブドメインを持たないURLでのみ動作します

def urlextract(url):
  url_split=url.split(".")
  if len(url_split) <= 2:
      raise Exception("Full url required with subdomain:",url)
  return {'subdomain': url_split[0], 'domain': url_split[1], 'suffix': ".".join(url_split[2:])}
0
Korayem

したがって、使用できるwindow.locationではなく文字列だけがある場合は...

String.prototype.toUrl = function(){

if(!this && 0 < this.length)
{
    return undefined;
}
var original = this.toString();
var s = original;
if(!original.toLowerCase().startsWith('http'))
{
    s = 'http://' + original;
}

s = this.split('/');

var protocol = s[0];
var Host = s[2];
var relativePath = '';

if(s.length > 3){
    for(var i=3;i< s.length;i++)
    {
        relativePath += '/' + s[i];
    }
}

s = Host.split('.');
var domain = s[s.length-2] + '.' + s[s.length-1];    

return {
    original: original,
    protocol: protocol,
    domain: domain,
    Host: Host,
    relativePath: relativePath,
    getParameter: function(param)
    {
        return this.getParameters()[param];
    },
    getParameters: function(){
        var vars = [], hash;
        var hashes = this.original.slice(this.original.indexOf('?') + 1).split('&');
        for (var i = 0; i < hashes.length; i++) {
            hash = hashes[i].split('=');
            vars.Push(hash[0]);
            vars[hash[0]] = hash[1];
        }
        return vars;
    }
};};

使い方。

var str = "http://en.wikipedia.org/wiki/Knopf?q=1&t=2";
var url = str.toUrl;

var Host = url.Host;
var domain = url.domain;
var original = url.original;
var relativePath = url.relativePath;
var paramQ = url.getParameter('q');
var paramT = url.getParamter('t');
0
Thomas Paris