Как удалить поддомены, чтобы получить действительный корневой домен с помощью PHP? - PullRequest
2 голосов
/ 14 декабря 2011

Хорошо, вот что я ищу: из списка ссылок я зачищаю все, кроме доменов.В результате получается смешанный список доменов и доменных имен, которые представляют субдомены.

stackoverflow.com
security.stackexchange.com
whoknows.test.co.uk
you.get.it.by.now.dont.you.com

Что я хочу сделать, это обрезать все записи списка до их VALID (= только существующих) корневых доменов, например так:

stackoverflow.com
security.stackexchange.com
test.co.uk
-fail-

В настоящее время я разбиваю каждую строку на массив и обрабатываю свой список задом наперед, используя curl, чтобы проверить каждый потенциальный корневой домен на предмет его существования ... как только curl возвращает HTTP-код>= 200 и <400, я считаю, что корневой домен будет найден.Когда конец каждого потенциального поиска домена завершен, а действительный домен вообще не найден, домен считается несуществующим. </p>

input:  stackoverflow.com
test:   stackoverflow.com  - succeeds and is the root domain
result: stackoverflow.com  - valid root domain

input:  whoknows.test.co.uk
test:   co.uk              - fails
test:   test.co.uk         - succeeds (theoretically) and is the root domain
result: test.co.uk         - valid root domain        

input:  you.get.it.by.now.dont.you.com
test:   you.com                         - fails 
test:   dont.you.com                    - fails 
test:   now.dont.you.com                - fails 
test:   by.now.dont.you.com             - fails 
test:   it.by.now.dont.you.com          - fails 
test:   get.it.by.now.dont.you.com      - fails 
test:   you.get.it.by.now.dont.you.com  - fails 
result: you.get.it.by.now.dont.you.com  - invalid domain 

Есть ли альтернативный способ сделать это?Я хотел бы прекратить нагревать процессор моего веб-сервера с просмотром скручиваемостей от 2 до X (= почти неограниченным) для каждого домена в моем списке 100.000+.Кроме того, все эти поиски занимают много времени.Может быть - так я надеюсь - для этого есть более быстрое решение.

Подвох?Он должен работать с PHP.

Ответы [ 3 ]

1 голос
/ 14 декабря 2011

Существует множество сочетаний клавиш для получения того, что вам нужно.

Например, вы уже знаете, что .co.uk и .com являются TLD, поэтому, проверяя их, вы, очевидно, можете пропустить.1006 * Проблема со всеми другими сумасшедшими TLD.

Я предлагаю вам взглянуть на источник ruby-domain-name

Они много сделалиработы с использованием RFC и известных данных, чтобы попытаться правильно их обработать.

0 голосов
/ 08 июля 2013
class DomainUtils {
  function __construct(){

    //only these super domains
    $this->superDomains = array(
        '.com',
        '.gov',
        '.org',
        '.co.uk',
        '.info',
        '.co',
        '.net',
        '.me',
        '.tv',
        '.mobi'
    );  
  }

  //get super domain
  public function getMainDomain($domain = null){
    $domainChunks = explode('.', str_ireplace($this->superDomains, '', $domain));
    if(sizeof($domainChunks) == 0){
        return false;
    }
    foreach($domainChunks as $key => $domainChunk){
        if($key < sizeof($domainChunks) - 1){ 
            $domain = str_ireplace($domainChunk . '.', '', $domain); 
        }
    }
    return $domain;
  } 
}
0 голосов
/ 02 января 2012

Итак ...

Я уже давно возился с этим, разыскивая потенциальные узкие места, и через несколько дней назад и вперед я обнаружил, что на самом деле это CURL (который ждетчтобы отдельные серверы отвечали HTTP-кодом), что делает процесс медленнее, чем нужно.

В конце я выбрал другую функцию "gethostbyname", которая учитывает IP6 длярешить мою проблему (и) .

function my_gethostbyname($host, $try_a = FALSE) 
{
    $dns = gethostbynamel6($host, $try_a);
    if ($dns == FALSE) 
    { 
        return FALSE; 
    }
    else 
    { 
        return $dns[0]; 
    }
}
function gethostbynamel6($host, $try_a = FALSE) 
{
    $dns = array();
    $dns6 = @dns_get_record($host, DNS_AAAA);
    if($dns6!== FALSE)
    {
        $dns = array_merge($dns, $dns6);
    }
    if ($try_a == TRUE) 
    {
        $dns4 = @dns_get_record($host, DNS_A);
        if($dns4!== FALSE)
        {
            $dns = array_merge($dns, $dns4);
        }
    }
    else
    {
        $dns = $dns6;
    }
    $ip6 = array();
    $ip4 = array();
    foreach ($dns as $record) 
    {
        if ($record["type"] == "A") 
        {
            $ip4[] = $record["ip"];
        }
        if ($record["type"] == "AAAA") 
        {
            $ip6[] = $record["ipv6"];
        }
    }
    if (count($ip6) < 1) 
    {
        if ($try_a == TRUE) 
        {
            if (count($ip4) < 1) 
            {
                return FALSE;
            }
            else 
            {
                return $ip4;
            }
        }
        else 
        {
            return FALSE;
        }
    }
    else 
    {
        return $ip6;
    }
}

Как только первая часть домена фактически преобразуется в IP, (a) домен существует и (b) является корневым доменом.

Это избавляет меня от основного времени, и хитрость в том, что вы работаете так же медленно, как ваше разрешение DNS и некоторые микросеки.Опция curl, которую я использовал раньше, занимала около 3 секунд на вызов (иногда вплоть до полного интервала ожидания, который я установил до 20 секунд), в зависимости от времени отклика целевого сервера - если оно есть.это легко понять: я получаю список разрешающих доменов и - при необходимости - могу проверить те, которые используют curl «по требованию» или одно или несколько заданий CRON «с интервалом».

Я знаю, чтоэто своего рода обходной путь, но разделение проблемы на две задачи (1 = предварительная проверка корневого домена, 2 = проверка, возвращает ли домен ожидаемый HTTP-код) делает все это быстрее, чем попытка выполнить всю работу сразу, используя curl.

Из того, что я узнал из этого ...

  1. При проверке доменов сначала попытайтесь разрешить их, чтобы вы могли сэкономить время, которое наступает при превышении времени ожидания.с curl.
  2. Curl отлично подходит для многих задач, но это не самый умный способ попытаться сделать с ним все .
  3. Когда вы думаете, что не можете решитьпроблемам, чем вы пытались сделать, разбейте проблему на две или более частей и проверьте снова.Скорее всего, вы откроете для себя целый новый мир возможностей для улучшения того, что у вас есть.

Я надеюсь, что это избавит кого-то от бремени, связанного с похожей проблемой в течение нескольких недель.;)

...