Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Структура URL (Uniform Resource Locator)
URL — это стандартизированный способ адресации ресурсов в интернете. Каждый URL состоит из нескольких компонентов, каждый из которых имеет своё назначение.
Полная структура URL
https://user:password@example.com:8443/path/to/resource?key=value&foo=bar#section
├────┬────────────────────────────┬──────┬──────────────────┬─────────────────┬────────┤
│ │ │ │ │ │ │
Scheme Authority (Host Info) Port Path Query String Fragment
1. Scheme (протокол)
https://example.com/path
^^^^^^
scheme
Определяет, как обращаться к ресурсу.
Популярные схемы:
http://— HTTP, незащищённый, порт 80https://— HTTP с TLS, защищённый, порт 443ftp://— File Transfer Protocol, порт 21ws://— WebSocket, незащищённый, порт 80wss://— WebSocket Secure, защищённый, порт 443file://— локальный файлmailto:— email адресtel:— телефонный номер
from urllib.parse import urlparse
url = "https://example.com/path"
parsed = urlparse(url)
print(parsed.scheme) # 'https'
2. Authority (информация об авторизации)
https://user:password@example.com:8443/path
──────────────────────────────
authority
Авторити состоит из трёх частей:
a) Userinfo (опционально)
https://user:password@example.com/path
─────────────
userinfo
user— имя пользователяpassword— пароль- Редко используется в современных приложениях (security risk)
url = "https://admin:secret123@internal.example.com/api"
parsed = urlparse(url)
print(parsed.username) # 'admin'
print(parsed.password) # 'secret123'
# ⚠️ Не передавайте пароли в URL! Используйте Headers или Environment variables
b) Host (домен)
https://example.com:8443/path
───────────
host
Форматы:
- Доменное имя:
example.com,api.example.com,sub.domain.example.co.uk - IPv4:
192.168.1.1 - IPv6:
[2001:db8::1](в квадратных скобках) - localhost:
localhost,127.0.0.1
url = "http://192.168.1.100:8000/api"
parsed = urlparse(url)
print(parsed.hostname) # '192.168.1.100'
url_ipv6 = "http://[2001:db8::1]:8000/api"
parsed = urlparse(url_ipv6)
print(parsed.hostname) # '2001:db8::1'
c) Port (порт)
https://example.com:8443/path
────
port
Стандартные порты (опционально указываются):
- HTTP: 80 (если опустить, подразумевается)
- HTTPS: 443 (если опустить, подразумевается)
- FTP: 21
- SSH: 22
- PostgreSQL: 5432
- MySQL: 3306
- MongoDB: 27017
- Redis: 6379
url = "https://example.com/path" # port не указан
parsed = urlparse(url)
print(parsed.port) # None (подразумевается 443 для HTTPS)
url = "https://example.com:8443/path"
parsed = urlparse(url)
print(parsed.port) # 8443
print(parsed.hostname) # 'example.com'
3. Path (путь до ресурса)
https://example.com/api/v1/users/123?query=1
──────────────────
path
Характеристики:
- Начинается с
/ - Разделяется слешами
- Регистрочувствителен (обычно)
- Может быть пустой (подразумевается
/)
url = "https://example.com/api/users/123"
parsed = urlparse(url)
print(parsed.path) # '/api/users/123'
# Разбор пути
path_parts = parsed.path.strip('/').split('/')
print(path_parts) # ['api', 'users', '123']
# Кодирование спецсимволов в пути
from urllib.parse import quote
user_input = "hello world"
encoded = quote(user_input)
print(f"Path: /search/{encoded}") # /search/hello%20world
4. Query String (параметры запроса)
https://example.com/path?key1=value1&key2=value2&key3=value3
────────────────────────────────────────
query string
Характеристики:
- Начинается с
? - Пары ключ=значение, разделённые
& - Порядок не гарантирован
- Значения кодируются (URL encoding)
- Может быть пустой
from urllib.parse import urlparse, parse_qs, urlencode
url = "https://example.com/search?q=python&limit=10&offset=0"
parsed = urlparse(url)
# Получить строку запроса
print(parsed.query) # 'q=python&limit=10&offset=0'
# Распарсить в словарь
query_params = parse_qs(parsed.query)
print(query_params) # {'q': ['python'], 'limit': ['10'], 'offset': ['0']}
# Создать URL с параметрами
params = {'q': 'python', 'limit': 10, 'offset': 0}
query_string = urlencode(params)
print(f"https://example.com/search?{query_string}")
# https://example.com/search?q=python&limit=10&offset=0
# Спецсимволы кодируются
params = {'search': 'hello world', 'category': 'python tips'}
query_string = urlencode(params)
print(f"https://example.com/search?{query_string}")
# https://example.com/search?search=hello+world&category=python+tips
5. Fragment (якорь)
https://example.com/docs/api?version=2#authentication
──────────────
fragment
Характеристики:
- Начинается с
# - Используется для навигации внутри страницы
- Не отправляется на сервер (остаётся на клиенте)
- Обычно используется в SPA приложениях для маршрутизации
url = "https://example.com/page#section-2"
parsed = urlparse(url)
print(parsed.fragment) # 'section-2'
# Пример: SPA маршрутизация
url = "https://myapp.com/app#/users/123/profile"
parsed = urlparse(url)
print(parsed.fragment) # '/users/123/profile'
# На клиенте JavaScript прочитает этот фрагмент и отобразит нужный компонент
Примеры реальных URL
from urllib.parse import urlparse
# Пример 1: простой API запрос
url1 = "https://api.github.com/repos/pallets/flask"
parsed1 = urlparse(url1)
print(f"Host: {parsed1.hostname}") # api.github.com
print(f"Path: {parsed1.path}") # /repos/pallets/flask
# Пример 2: поисковый запрос
url2 = "https://www.google.com/search?q=python+programming&hl=en"
parsed2 = urlparse(url2)
print(f"Host: {parsed2.hostname}") # www.google.com
print(f"Path: {parsed2.path}") # /search
print(f"Query: {parsed2.query}") # q=python+programming&hl=en
# Пример 3: документация с якорем
url3 = "https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlparse"
parsed3 = urlparse(url3)
print(f"Path: {parsed3.path}") # /3/library/urllib.parse.html
print(f"Fragment: {parsed3.fragment}") # urllib.parse.urlparse
# Пример 4: localhost с портом
url4 = "http://localhost:8000/api/v1/users?limit=10"
parsed4 = urlparse(url4)
print(f"Hostname: {parsed4.hostname}") # localhost
print(f"Port: {parsed4.port}") # 8000
print(f"Path: {parsed4.path}") # /api/v1/users
URL Encoding (% encoding)
Спецсимволы кодируются в URL:
from urllib.parse import quote, unquote
# Кодирование
text = "hello world!"
encoded = quote(text) # safe characters: /_.-~
print(encoded) # hello%20world%21
# С определённым набором безопасных символов
path = "/api/v1/users/john@example.com"
encoded = quote(path, safe="/") # Сохранить слеши
print(encoded) # /api/v1/users/john%40example.com
# Декодирование
decoded = unquote("hello%20world%21")
print(decoded) # hello world!
# Таблица кодирования
print("%20 = space")
print("%2F = /")
print("%3F = ?")
print("%23 = #")
print("%40 = @")
print("%3D = =")
print("%26 = &")
Построение URL
from urllib.parse import urljoin, urlunparse
# Способ 1: urljoin (относительные URL)
base = "https://example.com/api/v1/"
relative = "users/123"
full_url = urljoin(base, relative)
print(full_url) # https://example.com/api/v1/users/123
# Способ 2: urlunparse (все части вместе)
components = (
'https', # scheme
'example.com', # netloc
'/api/users', # path
'', # params
'limit=10&offset=0', # query
'results' # fragment
)
url = urlunparse(components)
print(url) # https://example.com/api/users?limit=10&offset=0#results
Валидация URL
from urllib.parse import urlparse
import re
def is_valid_url(url):
# Базовая проверка
try:
result = urlparse(url)
return all([result.scheme, result.netloc])
except Exception:
return False
print(is_valid_url("https://example.com")) # True
print(is_valid_url("not a url")) # False
print(is_valid_url("//example.com")) # False
# Более строгая регулярка
url_pattern = re.compile(
r'^https?://' # схема
r'(?:[a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+' # домен
r'(?:\.[a-zA-Z]{2,})' # TLD
r'(?::[0-9]+)?' # опциональный порт
r'(?:/[a-zA-Z0-9._~:/?#@!$&\'()*+,;=-]*)?$' # опциональный путь
)
print(url_pattern.match("https://example.com")) # Match
print(url_pattern.match("https://sub.example.co.uk:8443/path")) # Match
Best Practices
# ✅ Используйте urllib.parse для работы с URL
from urllib.parse import urlparse, parse_qs, urlencode, quote
# ✅ Всегда кодируйте пользовательский ввод в URL
user_input = request.args.get('search')
encoded = quote(user_input)
url = f"https://api.example.com/search?q={encoded}"
# ✅ Валидируйте URL перед использованием
if is_valid_url(url):
response = requests.get(url)
# ❌ Не конкатенируйте URL вручную
bad = f"https://example.com/search?q={user_input}" # vulnerable
# ❌ Не передавайте credentials в URL
bad = f"https://user:password@example.com/api" # security risk
# ✅ Используйте заголовки для авторизации
headers = {'Authorization': 'Bearer token123'}
response = requests.get(url, headers=headers)
Вывод
URL состоит из:
- Scheme — протокол (http, https, ftp)
- Authority — host и опциональные userinfo и port
- Path — путь к ресурсу
- Query — параметры запроса
- Fragment — якорь на странице
Понимание структуры URL — это essential skill для веб-разработчика. Правильная работа с URL гарантирует безопасность, читаемость и совместимость кода.