Comments 18
host microsoft.com
microsoft.com has address 20.112.250.133
microsoft.com has address 20.236.44.162
microsoft.com has address 20.70.246.20
microsoft.com has address 20.76.201.171
microsoft.com has address 20.231.239.246
microsoft.com has IPv6 address 2603:1020:201:10::10f
microsoft.com has IPv6 address 2603:1030:20e:3::23c
microsoft.com has IPv6 address 2603:1030:b:3::152
microsoft.com has IPv6 address 2603:1010:3:3::5b
microsoft.com has IPv6 address 2603:1030:c02:8::14
microsoft.com mail is handled by 10 microsoft-com.mail.protection.outlook.com.
Наверное правильно все же получать IP адрес из системного ресолвера.
Возможно вы правы. Но давайте представим ситуацию, когда у вас задействовано несколько потоков. Насколько получение из системного ресолвера будет тормозить процесс? И будет ли у нескольких потоков (возьмем threading) одновременный доступ к нему? Хотя, может я и ошибаюсь, не вникал настолько глубоко в эту тему. Но мне кажется, могут возникнуть проблемы. Или нет?
А в чем разница, между получением ip-адреса непосредственно из запроса к домену или socket с получением этого же адреса из ресолвера? И там, и там принцип работы схож. Что Windows, что Linux оправляют запросы на на все известные адреса DNS-серверов по порядку и ждут ответа. Что здесь происходит обращение к тем же серверам? Почему ваш способ правильнее?
Почему ваш способ правильнее?
Допустим, у сайта несколько ip адресов. Или сайт закрыт Великим Золотым Щитом. Или за прокси-сервером.
Насколько получение из системного ресолвера будет тормозить процесс?
Ни на сколько. А выполнение соединения по https и обработка редиректов - будет тормозить.
Да, если обрабатывать редиректы - есть шанс вместо microsoft.com узнать адрес www.microsoft.com.
Ну и если есть стандартный сервис разрешения имен - почему бы им не воспользоваться?
Ох уж эти х@керы.. Довольно спорный и странный способ получить адрес хоста.
getpeername
, скорее всего, будет возвращать ошибку если сокет закрыт. В приведенном примере он бы должен быть уже закрыт, но хз что там внутри делает requests в это время. Может быть кэширует что-то, а может и нет.
Даже если это и вернет что-то, то только адрес, к которому было установлено соединение. Причем, возможно, там был код 302 и запрос был несколько раз переадресован на другой хост (allow_redirects=True
). В общем-то, именно это и происходит в примере, поскольку в коде идет запрос на "http", а в ответе мы видим уже "https".
Если у хоста несколько адресов, то вы их никогда не узнаете.
В чём смысл всего этого вообще? Сделали два запроса к хосту, получили два разных адреса - что делать с ними?
Проверил код из статьи. Добавил в него socket.gethostbyname(domain). Ответ одинаковый
Из requests: 178.248.237.68, Из socket: 178.248.237.68
Ну вам повезло. Вот другой пример:
In [1]: import socket
In [2]: socket.gethostbyname('microsoft.com')
Out[2]: '20.112.250.133'
In [3]: socket.gethostbyname('microsoft.com')
Out[3]: '20.236.44.162'
In [4]: socket.gethostbyname('microsoft.com')
Out[4]: '20.231.239.246'
In [5]: socket.gethostbyname('microsoft.com')
Out[5]: '20.76.201.171'
Можете несколько раз вызвать через requests.
Опять же - зачем?
Вот именно, зачем? )) Опять же, в DNS записи "А" для домена мелкомягких указано 5 адресов. Достаточно одного. Целей может быть много, зачем адрес получать. Для примера, собрать информацию о домене.
Вы так активно защищаете статью, но приведите тогда уж реальный пример почему установка левой библиотеки и выполнение серии запросов (как минимум DNS и HTTP/TCP+TLS хендшейк ) будет лучше чем две строчки кода из stdlib?
Результат один и тот же, реального запроса к DNS, вероятно, даже не будет (несколько уровней кэша). Результат (возможно) вернет один случайный адрес из нескольких, назначенных этому имени, плюс сильно зависит от того как ваш запрос обработает балансер и приложение на другом конце.
"Собрать информацию о домене" - ну вот вы узнали что там был такой адрес. Что вам это даст? В следующий раз там будет другой адрес.
Достаточно одного.
Не возражаю ;)
Для примера, собрать информацию о домене.
Зачем собирать неполную информацию?
Если я правильно понял статью, то автор предлагает способ, с помощью которого можно не выполняя дополнительный запрос получить адрес, что сэкономит время при проверке большого количества адресов. Скорее всего так.
Да, я тоже так же понял статью. И, в свою очередь, попытался объяснить сколько раз автор неправ.
Думаю, что в данном случае, помимо получения ip-адреса, что не является основной целью, скорее является получение заголовков. Для примера, данный код можно объединить с другими библиотеками, с тем же wappalyzer для python, в который передать ответ. Только заменить head на get. И можно уже попробовать получить технологии используемые сайтом. Я пользовался похожим кодом, только получал ip через socket.
помимо получения ip-адреса, что не является основной целью
На данный момент заголовок статьи: "Получаем ip-адрес из requests (python)".
Ещё раз: используется обращение к внутренним свойствам объекта (уже плохо), при этом не гарантируется что сокет в это время открыт, что может вызвать ошибку. Уже это, само по себе, плохие рекомендации для статьи.
Единственный возможный смысл для всего этого - записать в лог что этот конкретный HTTP-запрос был обработан сервером по такому-то адресу, что может пригодиться разве что для внутреннего тестирования. Да и то есть более удобные способы логировать такое.
А здесь проверил с помощью dns resolver. Забрал "А" записи для IPv4 адресов. Получил в ответе то же, что и с помощью предыдущего кода. Да, это ip-адрес домена habr.com: 178.248.237.68
except Exception? Это антипаттерн. Классика - если ошибка, то ексепшен не даст полезной информации. И вся конструкция теряет смысл
Получаем ip-адрес из requests (python)