Pull to refresh

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) одновременный доступ к нему? Хотя, может я и ошибаюсь, не вникал настолько глубоко в эту тему. Но мне кажется, могут возникнуть проблемы. Или нет?

А как вы думаете, откуда requests берет эти адреса?

А в чем разница, между получением 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? Это антипаттерн. Классика - если ошибка, то ексепшен не даст полезной информации. И вся конструкция теряет смысл

Sign up to leave a comment.

Articles