Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsUse urllib.parse.unquote() to decode percent-encoded URL components. Use unquote_plus() for form-style values, where + means a space, and use parse_qs() or parse_qsl() to extract fields from a complete query string. If you need bytes rather than text, use unquote_to_bytes().
Choose the right decoding function
URL decoding depends on what the input represents. A path segment, a form value, and a complete query string are different inputs; applying the same function to all of them can change their meaning.
| Input or goal | Use | Behavior |
|---|---|---|
| A percent-encoded component that should become text | unquote() |
Replaces percent escapes such as %20; a plus sign remains a plus. |
| A value encoded using HTML form conventions | unquote_plus() |
Decodes percent escapes and changes + to a space. |
| A full query string parsed into named fields | parse_qs() |
Returns a dictionary whose values are lists. |
| A full query string where pair order or repeated pairs matter | parse_qsl() |
Returns a list of name/value pairs. |
| Decoded octets rather than decoded text | unquote_to_bytes() |
Returns bytes. |
Python documents these APIs in its urllib.parse reference.
Decode a URL component as text
For a percent-encoded path segment or other component, call unquote(). Its default text encoding is UTF-8:
#1 Best Overall
from urllib.parse import unquote
encoded_path = "/El%20Ni%C3%B1o/"
decoded_path = unquote(encoded_path)
print(decoded_path)
# /El Niño/
%20 becomes a space, and the UTF-8 percent escapes for ñ become that character. unquote() does not treat + as a space, which is normally the appropriate behavior for an ordinary URL component.
Use plus-to-space decoding only for form values
In form-style encoding, a plus sign represents a space. Use unquote_plus() when the input is a form-encoded value, not just because it contains percent escapes:
from urllib.parse import unquote_plus
value = unquote_plus("name=Ada+Lovelace")
print(value)
# name=Ada Lovelace
If a plus sign is literal data in an ordinary component, unquote_plus() would incorrectly turn it into a space. The form-specific behavior is why Python provides both functions.
Rank #2
Parse a complete query string
When the input is a query string with named parameters, parse it instead of manually decoding the entire string. parse_qs() is convenient when a mapping is useful; each key maps to a list so repeated parameter names can be represented.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
from urllib.parse import parse_qs
params = parse_qs("name=Ada+Lovelace&tag=python")
print(params)
# {'name': ['Ada Lovelace'], 'tag': ['python']}
Use parse_qsl() when you need the parameters as an ordered sequence of pairs:
from urllib.parse import parse_qsl
pairs = parse_qsl("tag=python&tag=urls&name=Ada")
print(pairs)
# [('tag', 'python'), ('tag', 'urls'), ('name', 'Ada')]
Both functions are intended to reverse query-string encoding into Python data structures. Parsing the query as a whole preserves the distinction between parameter names and values.
Return bytes when text decoding is not what you need
unquote_to_bytes() decodes percent escapes to octets and returns a bytes object. This is useful when a later step expects binary data or when you need to control text decoding yourself.
from urllib.parse import unquote_to_bytes
data = unquote_to_bytes("caf%C3%A9")
print(data)
# b'cafxc3xa9'
When its input is a string, unescaped non-ASCII characters are encoded as UTF-8 bytes. Decode those bytes to text separately if that is what your application needs.
Recommended Free Tools
Understand malformed escapes and version behavior
For unquote(), the default text encoding is UTF-8 and the default error handling is 'replace'. If decoded byte sequences are not valid under the selected encoding, invalid sequences are replaced rather than raising an error. Specify encoding or errors if your application requires different behavior.
The current Python 3.14 documentation notes that unquote() accepted only str before Python 3.9; support for bytes input was added in Python 3.9. Check the documentation for the Python version you deploy if your code depends on version-specific behavior.
Decoding does not validate or secure a URL
Decoding answers how escapes map back to characters or bytes. It does not establish that a URL is well-formed, safe, or allowed by your application. Python’s documentation cautions that URL parsing functions do not validate inputs. After parsing or decoding untrusted input, validate the components and apply the rules your application requires before using them.
Avoid decoding the same value repeatedly unless the format explicitly requires it. A second decoding pass can turn text that was intentionally percent-escaped into active delimiters or other data, changing how downstream code interprets the value.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Best Value
Or skip the browser setup
URL decoding is a Python parsing task; ScreenshotNeo is for the separate task of capturing a web page as an image or PDF. If your workflow needs a screenshot after you have a page URL, one GET request can capture it:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are not billed. It also provides an MCP server for AI agents, and its free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Learn about ScreenshotNeo or sign up for 1,000 free screenshots a month with no card.
Frequently Asked Questions
Does `unquote()` decode an entire URL into a usable URL object?
No. It replaces percent escapes in a string; it does not split a URL into scheme, host, path, and query components. Use the appropriate parsing function for the structure you need.
What does `unquote()` do with an invalid UTF-8 sequence by default?
Its default error mode is `replace`, so invalid sequences are replaced. Set the `errors` argument deliberately if replacement is unsuitable for your application.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




