Когда мы получаем какую-либо информацию о домене, в числе прочих параметров мы узнаем его ip-адрес. И получить его с помощью python не составляет большого труда. Однако давайте рассмотрим, как, не используя прямое обращение к сокету получить ip-адрес непосредственно из запроса.
Зачастую, чтобы получить ip-адрес мы используем socket. И в случае, когда нам требуется выполнение только данной операции этого вполне достаточно.
print(socket.gethostbyname("python.org"))
Но можно поступить несколько иначе, особенно если мы уже получаем какие-либо данные с сервера. Хотя бы те же заголовки. Давайте на примере посмотрим, как реализовать получение доступа к необработанному объекту сокета.
Установка необходимых библиотек
В данном случае нам понадобиться библиотека requests. Для ее установки пишем в терминале:
pip install requests
Импорт библиотек в скрипт. Создание заголовков для запроса
После того, как установлены необходимые библиотеки, нам их нужно импортировать в скрипт. В данном случае, так как мы установили библиотеку requests, импортируем ее.
import requests
После этого создадим словарь с заголовками содержащими «User-Agent» и «Accept». Их мы будем передавать в запрос в качестве параметра, чтобы изменить стандартные заголовки отправляемые python.
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 "
"YaBrowser/24.1.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,"
"application/signed-exchange;v=b3;q=0.7"
}
Получаем заголовки и ip-адрес
Создадим функцию get_domain_info(domain: str) -> (dict, bool), которая на входе будет получать домен, а возвращать заголовки отправленные сервером, а также ip-адрес домена.
Выполним запрос на получение заголовков, куда передадим адрес домена, заголовки. Укажем свойство allow_redirects = True. Это сделано для того, чтобы производилась переадресация. То есть, в данном случае мы делаем следующее: так как мы не знаем точного адреса сайта, доменное имя которого передано в функцию, поступим как браузер. Для начала пойдем по протоколу http. Если на сервере включена переадресация, то мы будем автоматически переадресованы на нужный адрес. Также, stream=True. Это необходимо для получения ip-адреса из запроса.
Обработаем исключение raise_for_status(), чтобы отсекать ненужные статус-коды. В случае же, когда код 200, получим ip и порт, которые возвращаются в кортеже при выполнении следующего кода: res.raw._connection.sock.getpeername(). Важно то, что эти данные необходимо получить в самом начале, до обработки остальных данных запроса, то есть в первую очередь. И уже после получим частично содержимое из заголовков отправленных сервером. Вернем пользователю словарь из полученных данных. В случае же неудачи или неверного статус-кода, вернем из функции False.
def get_domain_info(domain: str) -> (dict, bool):
try:
res = requests.head(url=f"http://{domain}", headers=headers, stream=True, allow_redirects=True, timeout=5)
try:
res.raise_for_status()
ip, port = res.raw._connection.sock.getpeername()
serv = res.headers.get("Server")
x_powered_by = res.headers.get('X-Powered-By')
via = res.headers.get('Via')
return {"ip": ip, "port": port, "addr": res.url, "server": serv, "x_powered_by": x_powered_by, "via": via}
except Exception:
return False
except Exception:
return False
Ну и создадим функцию main, где и будем запрашивать у пользователя домен, отправлять его в функцию для получения информации и выводить на печать полученные в виде словаря данные.
def main() -> None:
domain = input("Введите домен: ")
print(get_domain_info(domain))
if __name__ == "__main__":
main()
Здесь я не проверяю полученную информацию, так как данный код служит примером. Если вы попробуете получить ip-адрес с помощью socket, результат, зачастую, будет одинаковым. Однако, если вы увидите, что адреса различаются, то не считайте это ошибкой. Я проверял специально данные, получая информацию от DNS. Тут дело в том, что на одном домене может быть несколько NS-серверов. И в этом случае возвращается значение ближайшего. Ну или свободного. В данном случае механизм для меня пока еще не совсем понятен. Главное, что и тот, и тот адреса являются правильными.
Полный код скрипта
"""
pip install requests
"""
import requests
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 "
"YaBrowser/24.1.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,"
"application/signed-exchange;v=b3;q=0.7"
}
def get_domain_info(domain: str) -> (dict, bool):
try:
res = requests.head(url=f"http://{domain}", headers=headers, stream=True, allow_redirects=True, timeout=5)
try:
res.raise_for_status()
ip, port = res.raw._connection.sock.getpeername()
serv = res.headers.get("Server")
x_powered_by = res.headers.get('X-Powered-By')
via = res.headers.get('Via')
return {"ip": ip, "port": port, "addr": res.url, "server": serv, "x_powered_by": x_powered_by, "via": via}
except Exception:
return False
except Exception:
return False
def main() -> None:
domain = input("Введите домен: ")
print(get_domain_info(domain))
if __name__ == "__main__":
main()
Протестируем написанный код и получим заголовки и ip-адрес для домена python.org.
Как видим, скрипт отработал правильно и вернул ip-адрес, а также информацию из полученных заголовков.
А на этом, пожалуй, все.
Спасибо за внимание. Надеюсь, данная информация будет вам полезна!
Подписывайся на наши телеграм каналы! У нас много полезного!