Как в query-параметр передать знак амперсанда (&)?
Что проверяют
Понимаете ли вы, что & в URL служебный символ и значение нужно процентно кодировать, и умеете ли делать это инструментами Python, а не склейкой строк. Следом обычно спрашивают, чем quote отличается от quote_plus и что будет с пробелом и плюсом.
Как отвечать
В строке запроса & разделяет пары, а = отделяет имя от значения. Если значение содержит &, сервер увидит лишний параметр. Решение: процентное кодирование по RFC 3986, & превращается в %26, и сервер при разборе вернёт исходный символ.
Инструменты в Python:
urllib.parse.urlencode: принимает словарь или список пар и кодирует всё сразу:urlencode({"q": "Tom & Jerry"})даётq=Tom+%26+Jerry. По умолчанию используетquote_plus, поэтому пробел становится+;quoteиquote_plus: кодируют одно значение.quoteпо умолчанию не трогает/(параметрsafe='/'), для значения запроса передавайтеsafe=''.quote_plusкодирует пробел как+,quoteкак%20;requestsиhttpx: параметрparams={"q": "Tom & Jerry"}, библиотека закодирует сама. В прикладном коде это лучший вариант;- обратная операция:
parse_qsиparse_qslраскодируют строку, а FastAPI и Django отдают в обработчик уже раскодированное значение.
Главная мысль: кодируется каждое значение отдельно, а не весь URL целиком. Если закодировать готовую строку, разделители & и = тоже превратятся в %26 и %3D, и сервер получит один параметр вместо нескольких.
Где спотыкаются
Путают URL-кодирование с HTML-сущностью &. Она экранирует & только в разметке, браузер превратит её обратно в разделитель, и значение всё равно разорвётся. Внутри значения нужен %26.
Забывают про плюс. В строке запроса + читается как пробел, поэтому C++ без кодирования придёт как C и два пробела. Нужен %2B, его quote_plus и urlencode поставят сами.
Кодируют дважды: значение уже прошло через quote, а потом его отдают в params у requests. Получается %2526, и сервер видит буквальный текст %26.