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

Я успешно использую pythonwhois (установлен с pip install ...) для проверки доступности доменов .com:

import pythonwhois
for domain in ['aaa.com', 'bbb.com', ...]:
    details = pythonwhois.get_whois(domain)
    if 'No match for' in str(details):   # simple but it works!
        print domain 

Но:

  • это немного медленно (в среднем 2 запроса в секунду)
  • не попаду ли я в черный список сервера whois, если я сделаю 26*26*26 ~ 17000 запросов?
    (я проверяю доступность ???mail.com, где ? равно a..z)

Вопрос: есть ли лучший способ проверить доступность, чем выполнение одного запроса whois для каждого домена?


Изменить: задание завершено за 9572 секунды, и вот полный список всех доступных доменов формы ???mail.com, по состоянию на ноябрь 2017 года, если кто-то заинтересован в запуске службы электронной почты!


person Basj    schedule 21.11.2017    source источник


Ответы (1)


Вы должны распараллелить то, что делаете. Поскольку большую часть времени ваша функция тратит на ожидание, вы можете проверить сразу много работ (не ограничиваясь количеством ваших процессоров). Пример:

import pythonwhois
from joblib import Parallel, delayed, cpu_count
n_jobs = 100 # works in parallel
def f(domain):
    details = pythonwhois.get_whois(domain)
    if 'No match for' in str(details):   # simple but it works!
        print(domain)
        return domain
    else:
        return None

domains= ['aaa.com', 'bbb.com', 'ccc.com', 'bbbaohecraoea.com']
result = Parallel(n_jobs=n_jobs, verbose=10)(delayed(f)(domain) for domain in domains)

# create a list with the available domains
available_domains=[domains[idx] for idx,r in enumerate(result) if r!=None]
print(available_domains)
# Result
# ['bbbaohecraoea.com']
person silgon    schedule 21.11.2017
comment
Вау, это выглядит очень красиво, я никогда раньше не использовал Parallel! (Просто ошибка с вашим кодом: ImportError: [joblib] Attempting to do parallel computing without protecting your import on a system that does not support forking. To use parallel-computing in a script, you must protect your main loop using "if __name__ == '__main__'". Please see the joblib documentation on Parallel for more information) (Я использую Python 2.7 с Windows). - person Basj; 21.11.2017
comment
Итак, я добавил if __name__ == '__main__':, и затем он запускается, но тогда у меня нет другого вывода, кроме [Parallel(n_jobs=10)]: Done 5 tasks | elapsed: 1.7s [Parallel(n_jobs=10)]: Done 12 tasks | elapsed: 2.1s [Parallel(n_jobs=10)]: Done 21 tasks | elapsed: 2.5s [Parallel(n_jobs=10)]: Done 30 tasks | elapsed: 2.6s. Любая идея о том, как на самом деле отображать результаты? Я думаю, что print не имеют никакого эффекта. - person Basj; 21.11.2017
comment
Я добавил еще немного кода, чтобы показать вам доступные домены. Кроме того, в моем случае при импорте нет ошибки. Вероятно, это проблема версии или что-то в этом роде. - person silgon; 21.11.2017
comment
О, я вижу, это отображается не на лету, а в конце, при печати result... Есть ли способ печатать домены на лету (при этом) до конца? Кажется, что print(domain) в f() не отображается. - person Basj; 21.11.2017
comment
Возможно, это из-за версии, которую вы используете. С моей версией под линукс работает. Но то, что вас интересует, это только результат. Просто чтобы поиграться, я создал еще один скрипт, который создает 10000 случайных строк и проверяет их. - person silgon; 21.11.2017
comment
Хорошо, возможно, цифры были действительно амбициозными. Я изменил на n_jobs=100, и у меня все заработало. - person silgon; 21.11.2017
comment
Да, 100 намного лучше, 1000 произвели массовое замораживание / форкбомбу (сотни процессов python32.exe в диспетчере задач!) - person Basj; 22.11.2017