Поиск освобождающихся доменов

Знакомство с whois. Пишем свой парсер

Чтобы проверить доступность домена, можно вызвать команду whois с помощью Python, а затем проанализировать возвращаемый результат. Эту проверку также можно выполнить с помощью команд nslookup или dig.

WHOIS — это протокол запросов и ответов, который часто используется для запросов к базам данных, в которых хранятся зарегистрированные доменные имена. 

Пример запроса/ответа для доменного имени seo-python.ru

whois {domain_name}
Вывод команды whois

Код парсера whois

Проверяем последовательно все домены из списка domains. Вывод команды сохраняем в test_whois.txt.

os.system('whois '+ domain +  ' > test_whois.txt')

Далее из текста парсим Registry Expiry Date. На выходе получаем 2 файла:

  • whois_parser_pre_check_not_expired.csv — список активных доменов с предполагаемой датой освобождения
  • whois_parser_pre_check_possyble_expired.csv — список доступных для регистрации
import os
import re

domains = ['passportrequired.com']


with open('domain_not_response_3.csv', 'r') as file:
    for domain in file:
        domain = domain.strip()
        domains.append(domain)

print(domains)

for domain in domains:
    resp = os.system('whois '+ domain +  ' > test_whois.txt')


    if resp == 0:

        try:

            with open( 'test_whois.txt' ) as file:
                text_file = file.read()

                status = re.findall( r'status:\s+(.*)\n', text_file )[0]

                # breakpoint()


                if status == 'ACTIVE':

                    # Активные домены, у которых парсим Registry Expiry Date. Если достали значит домен занят
                    try:
                        registry_expiry_date = re.findall( r'Registry Expiry Date:\s+(.*)\n|Expires:\s+(.*)|Expiry date:\s+(.*)|expire:\s+(.*)|Registrar Registration Expiration Date:\s+(.*)', text_file )[0]

                        # парсим Expires несколькими регулярками ('', '2021-04-30'). Выбираем один вариант
                        for item in registry_expiry_date:
                            if len(item) !=0:
                                registry_expiry_date = item
                                break


                        print(domain, status, registry_expiry_date)
                        with open('whois_parser_pre_check_not_expired.csv', 'a') as file:
                            file.write(f'{domain}\t{status}\t{registry_expiry_date}\n')


                    # Если registry_expiry_date распарсить не получилось, вероятно свободен. Пишем отдельно для проверки
                    except Exception as e:
                        registry_expiry_date = ''

                        print(domain, e)

                        with open('whois_parser_pre_check_possyble_expired.csv', 'a') as file:
                            file.write(f'{domain}\t{status}\t{registry_expiry_date}\n')

                else:
                    print(domain, status)


        except Exception as e:
            # free_date = re.findall( r'free-date:\s+(.*)\n', text_file )[0]
            # paid_till = re.findall( r'paid-till:\s+(.*)\n', text_file )[0]
            # changed = re.findall( r'changed:\s+(.*)\n', text_file )[0]


            print(domain, e)

            registry_expiry_date = ''

            with open( 'whois_parser_pre_check_possyble_expired.csv', 'a' ) as file:
                file.write( f'{domain}\t{e}\t{registry_expiry_date}\n' )

Минусы

  • Парсим в 1 поток, при большом количестве доменов занимает много времени
  • Формат ответа команды whois может различаться, поэтому нужно дополнять регулярное выражение для парсинга registry_expiry_date

Проверка доступности домена с помощью сервисов

Что потребуется:

  • Список доменов на проверку
  • Ключи API whoisxmlapi
  • Установленные Python-библиотеки

WhoisXML API (платно, ограниченные бесплатные лимиты)

Парсинг whois api.whois.vu (бесплатно)

import random
from requests_html import HTMLSession
from queue import Queue
from threading import Lock
from concurrent.futures import ThreadPoolExecutor
import re
import os


lock = Lock()
os.chdir( '/Users/vladmedvedev/PycharmProjects/python for seo/Поиск дропов' )

def domain_availability(domain):

    for _ in range(5):

        url_api = f'http://api.whois.vu/?q={domain}'

        with HTMLSession() as session:

            try:
                response = session.get(url_api, timeout=20)

                #print(response.status_code)

                if response.status_code == 200:
                    break

                else:
                    response = None
                    # print(f'Ошибка.')

            except Exception as e:
                response = None

    return response


def get_info_domain_worker(qu):

    while True:

        domain = qu.get()

        try:
            response_domain = domain_availability(domain).json()

            domain_availabile = response_domain['available']

            print(domain, domain_availabile)

            if domain_availabile == 'yes':

                with lock:
                    with open('whois_parser_pre_check_possyble_expired.csv', 'a') as file:
                        file.write(f'{domain}\t{domain_availabile}\n')


            else:
                whois = response_domain['whois']
                registry_expiry_date = re.findall(r'Registry Expiry Date:\s+(.*)\n|Expires:\s+(.*)|Expiry date:\s+(.*)|expire:\s+(.*)|Registrar Registration Expiration Date:\s+(.*)|free-date:\s+(.*)', whois )[0]

                for item in registry_expiry_date:
                    if len( item ) != 0:
                        registry_expiry_date = item
                        break

                with lock:
                    with open('whois_parser_pre_check_not_expired.csv', 'a') as file:
                        file.write(f'{domain}\t{domain_availabile}\t{registry_expiry_date}\n')





        except Exception as e:

            print(domain, e, 'Ответ не получен. Сервис вернул "None", проверь токены и повтори проверку')

            with lock:
                with open('domain_recheck_3.csv', 'a') as file:
                    file.write(f'{domain}\n')

        if qu.empty():
            break


def main():

    domain_qu = Queue()

    worker_count = 10

    with open('/Users/vladmedvedev/PycharmProjects/python for seo/Поиск дропов/domain_not_response.csv', 'r') as file:

        for line in file:
            domain = line.strip()
            domain_qu.put(domain)


    with ThreadPoolExecutor(max_workers = worker_count) as executor:
        for _ in range(worker_count):
            executor.submit(get_info_domain_worker, domain_qu)


if __name__=='__main__':
    main()

Плюсы подходов

  • Парсинг в несколько поток
  • Проверка большего количество доменов

Минусы

  • При большом количество потоков сервисы могут перестать отвечать, результаты проверки будут искажены
  • Ограничения бесплатного api на 500 проверок для 1 ключа
Добавить комментарий 0

Ваш электронный адрес не будет опубликован. Обязательные поля помечены *