На этом шаге мы рассмотрим ряд функций, позволяющих выполнить указанные действия.
На предыдущем шаге мы научились разбирать URL-адрес на составляющие. Обратите внимание на то, что значение параметра <Запрос> возвращается в виде строки. Строка запроса является составной конструкцией, содержащей пары параметр=значение. Все специальные символы внутри названия параметра и значения кодируются последовательностями %nn. Например, для параметра str, имеющего значение "Строка" в кодировке Windows-1251, строка запроса будет выглядеть так:
str=%Dl%F2%F0%EE%EA%E0
Если строка запроса содержит несколько пар параметр=значение, то они разделяются символом &. Добавим параметр v со значением 10:
str=%Dl%F2%F0%EE%EA%E0&v=10
В строке запроса может быть несколько параметров с одним названием, но разными значениями,- например, если передаются значения нескольких выбранных пунктов в списке с множественным выбором:
str=%Dl%F2%F0%EE%EA%EG&v=10&v=20
Разобрать строку запроса на составляющие и декодировать данные позволяют следующие функции из модуля urllib.parse:
parse_qs (<Строка запроса> [, keep_blank_values=False] [, strict_parsing=False] [, encoding='utf-8' ] [, errors='replace' ])
Если в параметре keep_blank_values указано значение True, то параметры, не имеющие значений внутри строки запроса, также будут добавлены в результат. По умолчанию пустые параметры игнорируются. Если в параметре strict_parsing указано значение True, то при наличии ошибки возбуждается исключение ValueError. По умолчанию ошибки игнорируются. Параметр encoding позволяет указать кодировку данных, а параметр errors - уровень обработки ошибок. Пример разбора строки запроса:
>>> from urllib.parse import parse_qs >>> s = "str=%D1%F2%F0%EE%EA%E0&v=10&v=20&t=" >>> parse_qs(s, encoding="cp1251") {'v': ['10', '20'], 'str': ['Строка']} >>> parse_qs(s, keep_blank_values=True, encoding="cp1251") {'v': ['10', '20'], 'str': ['Строка'], 't': ['']}
parse_qsl (<Строка запроса> [, keep_blank_values=False] [, strict_parsing=False] [, encoding='utf-8' ] [, errors='replace' ])
Пример разбора строки запроса:
>>> from urllib.parse import parse_qsl >>> s = "str=%D1%F2%F0%EE%EA%E0&v=10&v=20&t=" >>> parse_qsl(s, encoding="cp1251") [('str', 'Строка'), ('v', '10'), ('v', '20')] >>> parse_qsl(s, keep_blank_values=True, encoding="cp1251") [('str', 'Строка'), ('v', '10'), ('v', '20'), ('t', '')]
Выполнить обратную операцию - преобразовать отдельные составляющие в строку запроса - позволяет функция urlencode(). Формат функции:
urlencode (<Объект> [, doseq=False] [, safe=''] [, encoding=None] [, errors=None])
В качестве первого параметра можно указать словарь с данными или последовательность, каждый элемент которой содержит кортеж из двух элементов: первый элемент такого кортежа станет параметром, а второй элемент - его значением. Параметры и значения автоматически обрабатываются с помощью функции quote_plus() из модуля urllib.parse. В случае указания последовательности параметры внутри строки будут идти в том же порядке, что и внутри последовательности. Пример указания словаря и последовательности приведен ниже.
>>> from urllib.parse import urlencode >>> params = {"str": "Строка 2", "var": 20} # Словарь >>> urlencode (params, encoding="cp1251") 'var=20&str=%D1%F2%F0%EE%EA%E0+2' >>> params = [ ("str", "Строка 2"), ("var", 20) ] # Список >>> urlencode (params, encoding="cp1251") 'str=%D1%F2%F0%EE%EA%E0+2&var=20'
Если необязательный параметр doseq в функции urlencode() имеет значение True, то во втором параметре кортежа можно указать последовательность из нескольких значений. В этом случае в строку запроса добавляются несколько параметров со значениями из этой последовательности. Значение параметра doseq по умолчанию - False. В качестве примера укажем список из двух элементов.
>>> params = [ ("var", [10, 20]) ] >>> urlencode(params, doseq=False, encoding="cp1251") 'var=%5B10%2C+20%5D' >>> urlencode(params, doseq=True, encoding="cp1251") 'var=10&var=20'
Последовательность также можно указать в качестве значения в словаре:
>>> params = { "var": [10, 20] } >>> urlencode(params, doseq=True, encoding="cp1251") 'var=10&var=20'
На следующем шаге мы закончим изучение этого вопроса.