В эпоху интернета URL (Uniform Resource Locator) является основным адресом, указывающим местоположение информации. В веб-разработке и анализе данных необходимо работать с URL, и иногда нужно извлекать лишь определенные его части (например, домен, путь, параметры запроса). Для этого в модуле Python urllib.parse есть функция urlparse(), которая является мощным инструментом.

В этой статье мы подробно рассмотрим основные способы использования функции urlparse(), значение и случаи использования часто используемого свойства .netloc, а также различные свойства объекта ParseResult, который возвращает urlparse().


1. Что такое urlparse()?



urlparse() - это функция, которая разбивает строку URL на несколько компонентов в соответствии со стандартами RFC 1738 (Universal Resource Locators in WWW) и RFC 3986 (Uniform Resource Identifier (URI): Generic Syntax). Каждый из этих компонентов возвращается в специальном объекте с именем ParseResult.

Основные способы использования

Функция urlparse() импортируется из модуля urllib.parse.

from urllib.parse import urlparse

url = 'https://user:pass@www.example.com:8080/path/to/resource?name=Alice&age=30#section1'
parsed_url = urlparse(url)

print(parsed_url)
# Вывод: ParseResult(scheme='https', netloc='user:pass@www.example.com:8080', path='/path/to/resource', params='', query='name=Alice&age=30', fragment='section1')

Объект parsed_url можно рассматривать как кортеж, используя индексы, или получить доступ к нему через именованные атрибуты. Второй способ гораздо более удобочитаем.


2. Основные свойства объекта ParseResult

Объект ParseResult, возвращаемый urlparse(), имеет следующие свойства.

scheme

  • Значение: Представляет собой часть протокола URL. (http, https, ftp, mailto и т. д.)

  • Пример: 'https'

netloc (Сетевое расположение)

  • Значение: Часть, которая включает имя хоста (домен), номер порта и, опционально, учетные данные пользователя (user:pass@).

  • Пример: 'user:pass@www.example.com:8080'

  • Использование: Полезно для извлечения только домена определенного веб-сервиса или для проверки номера порта для сетевого соединения. Об этом будет подробнее сказано далее.

path

  • Значение: Представляет собой путь к определенному ресурсу на веб-сервере.

  • Пример: '/path/to/resource'

params (Параметры пути)

  • Значение: Это параметры пути, разделенные точкой с запятой (;). Они определены в RFC, но почти не используются в современном веб-программировании, в основном используется запрос (query).

  • Пример: ';sessionid=xyz' (редко используется)

query

  • Значение: Это строка запроса, которая идёт после вопросительного знака (?). Используется для передачи данных на сервер в виде пар «ключ-значение».

  • Пример: 'name=Alice&age=30'

  • Использование: В сочетании с функцией urllib.parse.parse_qs() её можно легко распарсить в виде словаря.

from urllib.parse import parse_qs
query_params = parse_qs(parsed_url.query)
print(query_params)
# Вывод: {'name': ['Alice'], 'age': ['30']}

fragment

  • Значение: Идентификатор фрагмента, который идёт после символа хеш-тега (#). Обычно используется для перехода к определённой секции на веб-странице, не передается на сервер, а обрабатывается только браузером.

  • Пример: 'section1'


3. Глубокий анализ свойства .netloc



.netloc является особенно важным свойством среди результатов urlparse(). netloc - это аббревиатура от сетевого расположения (Network Location), и оно содержит ключевую информацию об адресе веб-сервера в URL.

netloc как компонент

netloc может состоять из следующих элементов.

  • Информация о пользователе (Userinfo): Включает имя пользователя и пароль в формате user:password@. Хотя это редко используется в общих веб-URL, можно встретить в таких протоколах как FTP.

  • Хост (Host): Имя домена (www.example.com) или IP-адрес (192.168.1.1).

  • Порт (Port): Номер порта, который идет после двоеточия (:). Если используется основной порт, например 80 для HTTP или 443 для HTTPS, номер порта может быть опущен в netloc.

Пример:

URL Результат .netloc Описание
https://www.example.com www.example.com Только домен (основной порт HTTPS 443 пропущен)
http://myhost:8000/app myhost:8000 Содержит хост и порт
ftp://user:pass@ftp.example.org user:pass@ftp.example.org Содержит информацию о пользователе и хост

Причины использования .netloc и сценарии

  1. Извлечение и верификация домена:

    • Легко извлечь часть домена с помощью netloc, чтобы узнать, с какого веб-сайта поступила просьба, для применения политики безопасности или разрешения только определенных доменов.

    • Используя свойство parsed_url.hostname, вы можете получить только имя хоста без номера порта.

url = 'https://www.example.com:8080/path'
parsed = urlparse(url)
print(parsed.netloc)    # 'www.example.com:8080'
print(parsed.hostname)  # 'www.example.com'
print(parsed.port)      # 8080 (int)
  1. Пересоздание или изменение URL:

    • Объект ParseResult, разбитый с помощью urlparse(), неизменяем (immutable), однако вы можете создать новый объект ParseResult, изменив только определенное свойство, используя метод .replace(). Такой измененный объект можно вновь передать функции urlunparse() для легкого пересоздания нового URL.

    • Например, при реализации редиректа к определенному домену можно изменить только netloc, чтобы сгенерировать новый URL.

from urllib.parse import urlparse, urlunparse

original_url = 'https://old.example.com/data'
parsed_original = urlparse(original_url)

# Создание нового URL, изменив только домен
new_netloc = 'new.example.com'
modified_parsed = parsed_original._replace(netloc=new_netloc)
new_url = urlunparse(modified_parsed)

print(new_url) # Вывод: https://new.example.com/data
  1. Сравнение идентичности URL (по домену/порту):

    • Когда необходимо узнать, указывают ли два URL на один и тот же сервер, полезно сравнивать значения свойства netloc.
url1 = 'https://api.myapp.com/v1/users'
url2 = 'https://api.myapp.com:443/v2/products' # 443 это основной порт для HTTPS
url3 = 'https://oldapi.myapp.com/v1/users'

parsed1 = urlparse(url1)
parsed2 = urlparse(url2)
parsed3 = urlparse(url3)

print(parsed1.netloc == parsed2.netloc) # True (основной порт можно не указывать и считать одинаковым)
print(parsed1.hostname == parsed2.hostname) # True
print(parsed1.netloc == parsed3.netloc) # False

4. Разница между urlparse() и urlsplit()

В модуле urllib.parse также есть функция urlsplit(), очень похожая на urlparse(). Основное различие между двумя функциями заключается в способе обработки параметра params.

  • urlparse(): Отделяет параметр params отдельно.

  • urlsplit(): Включает параметр params в атрибут path. Возвращает объект SplitResult вместо ParseResult и не имеет свойства params.

Поскольку параметр params почти не используется в современном веб-развитии, в большинстве случаев можно использовать urlsplit(). Но urlparse() предоставляет более общую и полную разбиение.


Заключение: Обязательный инструмент для анализа URL

Функция urlparse() на Python является мощным инструментом, который позволяет систематически разбирать сложные строки URL и извлекать необходимые части. Особенно свойство .netloc предоставляет информацию о хосте и порте, что делает его крайне полезным при обработке логики, основанной на домене, или пересоздании URL.

Для всех разработчиков на Python, работающих с URL, будь то веб-скрапинг, обработка API-запросов или проверка безопасности, функция urlparse() является обязательным знанием. Используйте эту функцию, чтобы более эффективно контролировать и использовать данные URL.

Схема urlparse