Содержание
Знакомство с whois. Пишем свой парсер
Чтобы проверить доступность домена, можно вызвать команду whois с помощью Python, а затем проанализировать возвращаемый результат. Эту проверку также можно выполнить с помощью команд nslookup или dig.
WHOIS — это протокол запросов и ответов, который часто используется для запросов к базам данных, в которых хранятся зарегистрированные доменные имена.
Пример запроса/ответа для доменного имени seo-python.ru
whois {domain_name}
Код парсера 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 ключа