October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk4 min

How to Decode URLs in Python

Use Python’s unquote() for percent-encoded components, unquote_plus() for form values, and parse_qs() or parse_qsl() for complete query strings.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use 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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. Shenzhen desk3 min
    HONOR Expands Beyond Smartphones With Humanoid Robot RevealHONOR said it unveiled its first humanoid robot at MWC 2026 and named shopping assistance, workplace inspections, and supportive companionship as intended uses. Later Robotics D1 claims and a reported…
  2. Cupertino desk5 min
    Apple Unveils AirPods Max 2: The Upgrade That Should Have Happened Years AgoAirPods Max 2 adds H2-powered audio features and Apple claims up to 1.5× more effective ANC, but its design, Smart Case, and 20-hour battery rating are unchanged. Wired lossless audio…
  3. Cupertino desk4 min
    Apple’s OLED Touch MacBooks Are Coming—but the Dynamic Island Is the Real GambleApple has not announced an OLED touchscreen MacBook, but reports point to high-end models arriving in late 2026 or early 2027. The reported Mac Dynamic Island could be useful, but…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.