Of course! Here's a detailed explanation of how to use urlencode in Python 2, covering the standard library method and the common pitfalls when dealing with Unicode strings.

The Standard Way: urllib.urlencode
In Python 2, the urlencode function is located in the urllib module. Its primary purpose is to convert a dictionary of key-value pairs into a query string suitable for a URL.
Basic Usage with a Dictionary
This is the most common use case. You have a dictionary and want to turn it into key1=value1&key2=value2.
import urllib
# A dictionary of parameters
params = {
'q': 'python tutorial',
'page': 2,
'sort': 'relevance'
}
# Convert the dictionary to a query string
query_string = urllib.urlencode(params)
print query_string
Output:
page=2&q=python+tutorial&sort=relevance
Notice that spaces are automatically converted to signs, which is standard for application/x-www-form-urlencoded data.

Usage with a List of Tuples
You can also provide a list of (key, value) tuples. This is useful if you have multiple values for the same key (though for that, a dictionary of lists is often cleaner).
import urllib
# A list of (key, value) tuples
params_list = [
('name', 'John Doe'),
('email', 'john.doe@example.com'),
('interests', 'coding'),
('interests', 'reading')
]
query_string = urllib.urlencode(params_list)
print query_string
Output:
name=John+Doe&email=john.doe%40example.com&interests=coding&interests=reading
Notice that the symbol in the email was automatically percent-encoded to %40.
The Crucial Difference: Python 2 vs. Python 3
This is the most important thing to remember when working with Python 2.
- Python 2:
urllib.urlencode()(all lowercase) - Python 3:
urllib.parse.urlencode()(part of theurllib.parsesub-module)
If you try to use the Python 3 syntax in Python 2, you will get an ImportError.
# THIS WILL FAIL IN PYTHON 2 # from urllib.parse import urlencode # <-- ImportError: No module named parse
Handling Unicode Strings in Python 2 (The Pitfall)
A very common issue in Python 2 is how to handle non-ASCII characters (like accents, Chinese characters, etc.). Python 2 has a str type (bytes) and a unicode type.
If your dictionary values are unicode strings, urlencode will fail with a UnicodeEncodeError.
import urllib
# This will FAIL in Python 2
# params_unicode = {
# 'user': 'José', # This is a unicode string in Python 2
# 'city': 'São Paulo'
# }
# query_string = urllib.urlencode(params_unicode)
# print query_string
# --> UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9'...
The Solution: Encode to UTF-8
You must first encode your unicode strings into a byte string (like UTF-8) before passing them to urlencode.
Method 1: Manually Encoding (Explicit)
You can loop through your dictionary and encode the values.
import urllib
params_unicode = {
'user': u'José', # u'' denotes a unicode string in Python 2
'city': u'São Paulo'
}
# Manually encode unicode values to UTF-8 byte strings
params_utf8 = {key: value.encode('utf-8') for key, value in params_unicode.items()}
query_string = urllib.urlencode(params_utf8)
print query_string
Output:
city=S%C3%A3o+Paulo&user=Jos%C3%A9
Here, became %C3%A9 and became %C3%A3, which is the correct UTF-8 percent-encoding.
Method 2: The doseq Parameter (Best for Multiple Values)
If you have a dictionary where one key maps to a list of values (e.g., {'tags': ['python', 'web']}), you should use the doseq=True argument. This prevents urlencode from URL-encoding the list brackets and commas.
import urllib
params_with_lists = {
'name': 'John Doe',
'tags': ['python', 'web', 'api']
}
# Without doseq=True, you get: tags=%5B%27python%27%2C+%27web%27%2C+%27api%27%5D
# With doseq=True, you get the correct format: tags=python&tags=web&tags=api
query_string = urllib.urlencode(params_with_lists, doseq=True)
print query_string
Output:
name=John+Doe&tags=python&tags=web&tags=api
Complete Example: Building a Full URL
Here is a practical example of building a complete URL with a query string.
import urllib
# 1. Define your parameters (with unicode)
search_params = {
'query': u'café', # unicode string
'location': u'paris'
}
# 2. Encode unicode values to UTF-8 byte strings
encoded_params = {k: v.encode('utf-8') for k, v in search_params.items()}
# 3. Create the query string
query_string = urllib.urlencode(encoded_params)
# 4. Build the full URL
base_url = "http://example.com/search"
full_url = base_url + '?' + query_string
print "Full URL:"
print full_url
Output:
Full URL:
http://example.com/search?query=caf%C3%A9&location=paris
Summary and Best Practices for Python 2
- Import Correctly: Always use
import urllib. - Handle Unicode: If your keys or values contain non-ASCII characters, they must be
unicodestrings. You must then encode them to a byte string (like UTF-8) before passing them tourlencode. - Use Dict Comprehension: A clean way to encode is
{k: v.encode('utf-8') for k, v in my_dict.items()}. - Use
doseq=True: If your dictionary values are lists, always adddoseq=Trueto get the correctkey=value1&key=value2format. - Plan for Python 3: If you are maintaining code that might be run on Python 3, consider using a compatibility library like
sixor atry...exceptblock to handle the different import paths.
