How can I percent-encode URL parameters in Python?
Python 2
From the documentation:
urllib.quote(string[, safe])
Replace special characters in string
using the %xx escape. Letters, digits,
and the characters '_.-' are never
quoted. By default, this function is
intended for quoting the path section
of the URL.The optional safe parameter
specifies additional characters that
should not be quoted — its default
value is '/'
That means passing ''
for safe will solve your first issue:
>>> urllib.quote('/test')
'/test'
>>> urllib.quote('/test', safe='')
'%2Ftest'
About the second issue, there is a bug report about it. Apparently it was fixed in Python 3. You can workaround it by encoding as UTF-8 like this:
>>> query = urllib.quote(u"Müller".encode('utf8'))
>>> print urllib.unquote(query).decode('utf8')
Müller
By the way, have a look at urlencode.
Python 3
In Python 3, the function quote
has been moved to urllib.parse
:
>>> import urllib.parse
>>> print(urllib.parse.quote("Müller".encode('utf8')))
M%C3%BCller
>>> print(urllib.parse.unquote("M%C3%BCller"))
Müller
Percent-encoding a string in Python
There are a number of ways to do this - a few are described here: How to urlencode a querystring in Python?
Basically you're trying to perform "URL encoding". String replace and/or regex are not the best options for this, as you guessed, since there are several builtin options to take care of things for you (such as some non-obvious conversions that need to be handled)
...and don't use the first option shown on that linked page - you probably want to use
urllib.parse.quote_plus(...)
How to prevent python requests from percent encoding my URLs?
It is not good solution but you can use directly string
:
r = requests.get(url, params='format=json&key=site:dummy+type:example+group:wheel')
BTW:
Code which convert payload
to this string
payload = {
'format': 'json',
'key': 'site:dummy+type:example+group:wheel'
}
payload_str = "&".join("%s=%s" % (k,v) for k,v in payload.items())
# 'format=json&key=site:dummy+type:example+group:wheel'
r = requests.get(url, params=payload_str)
EDIT (2020):
You can also use urllib.parse.urlencode(...)
with parameter safe=':+'
to create string without converting chars :+
.
As I know requests
also use urllib.parse.urlencode(...)
for this but without safe=
.
import requests
import urllib.parse
payload = {
'format': 'json',
'key': 'site:dummy+type:example+group:wheel'
}
payload_str = urllib.parse.urlencode(payload, safe=':+')
# 'format=json&key=site:dummy+type:example+group:wheel'
url = 'https://httpbin.org/get'
r = requests.get(url, params=payload_str)
print(r.text)
I used page https://httpbin.org/get to test it.
percent encoding URL with python
Use
urllib.quote_plus(url, safe=':')
Since you don't want the colon encoded you need to specify that when calling urllib.quote()
:
>>> expected = 'https:%2F%2Fdl.dropbox.com%2Fu%2F94943007%2Ffile.kml'
>>> url = 'https://dl.dropbox.com/u/94943007/file.kml'
>>> urllib.quote(url, safe=':') == expected
True
urllib.quote()
takes a keyword argument safe
that defaults to /
and indicates which characters are considered safe and therefore don't need to be encoded. In your first example you used ''
which resulted in the slashes being encoded. The unexpected output you pasted below where the slashes weren't encoded probably was from a previous attempt where you didn't set the keyword argument safe
at all.
Overriding the default of '/'
and instead excluding the colon with ':'
is what finally yields the desired result.
Edit: Additionally, the API calls for spaces to be encoded as plus signs. Therefore urllib.quote_plus()
should be used (whose keyword argument safe
doesn't default to '/'
).
How to URL encode in Python 3?
You misread the documentation. You need to do two things:
- Quote each key and value from your dictionary, and
- Encode those into a URL
Luckily urllib.parse.urlencode
does both those things in a single step, and that's the function you should be using.
from urllib.parse import urlencode, quote_plus
payload = {'username':'administrator', 'password':'xyz'}
result = urlencode(payload, quote_via=quote_plus)
# 'password=xyz&username=administrator'
python: encode a url with percentage signs?
Use urllib.quote()
for the url path
leaving everything else as is:
from urllib import quote
from urlparse import urlparse, urlunparse
url = "http://www.website.com/search/si/1/doctors/Vancouver, BC"
scheme, netloc, path, params, query, fragment = urlparse(url)
path = quote(path)
print urlunparse((scheme, netloc, path, params, query, fragment))
prints:
http://www.website.com/search/si/1/doctors/Vancouver%2C%20BC
See also:
- How can I normalize a URL in python
python requests module request params encoded url is different with the intended url
You can manually encode your _params
to construct your query string and then concatenate it to your _url
.
You can use
urllib.parse.urlencode
[Python-Docs] to convert
your_params
dictionary to a percent-encoded ASCII text string. The resulting
string is a series ofkey=value
pairs separated by&
characters,
where both key and value are quoted using thequote_via
function. By
default,quote_plus()
is used to quote the values, which
means spaces are quoted as a+
character and/
characters are
encoded as%2F
, which follows the standard for GET requests
(application/x-www-form-urlencoded). An alternate function that can be
passed asquote_via
isquote()
, which will encode spaces
as%20
and not encode/
characters. For maximum control of what is
quoted, usequote
and specify a value for safe.
from urllib.parse import quote_plus, quote, urlencode
import requests
url_template = "http://something/?{}"
_headers = { ... }
_params = {"action": "log", "datetime": "0900 (대한민국 표준시)"}
_url = url_template.format(urlencode(_params, safe="()", quote_via=quote))
response = requests.get(_url, headers=_headers)
How to urlencode a querystring in Python?
You need to pass your parameters into urlencode()
as either a mapping (dict), or a sequence of 2-tuples, like:
>>> import urllib
>>> f = { 'eventName' : 'myEvent', 'eventDescription' : 'cool event'}
>>> urllib.urlencode(f)
'eventName=myEvent&eventDescription=cool+event'
Python 3 or above
Use urllib.parse.urlencode
:
>>> urllib.parse.urlencode(f)
eventName=myEvent&eventDescription=cool+event
Note that this does not do url encoding in the commonly used sense (look at the output). For that use urllib.parse.quote_plus
.
Python percent encoding only certain characters in a URL
How about a.replace('#','%23')
?
Related Topics
How to Execute Raw SQL in Flask-Sqlalchemy App
Parallel Processing from a Command Queue on Linux (Bash, Python, Ruby... Whatever)
Name This Python/Ruby Language Construct (Using Array Values to Satisfy Function Parameters)
Numpy Selecting Specific Column Index Per Row by Using a List of Indexes
How to Make a Cross-Module Variable
Priority of the Logical Operators Not, And, or in Python
Str' Object Does Not Support Item Assignment
Importerror: Matplotlib Is Required for Plotting When the Default Backend "Matplotlib" Is Selected
Basic Python Hello World Program Syntax Error
Differencebetween Installing a Package Using Pip VS. Apt-Get
How to Directly Send a Python Output to Clipboard
Run a Linux System Command as a Superuser, Using a Python Script
R and Python in One Jupyter Notebook
R Expand.Grid() Function in Python
Conda Reports Packagesnotfounderror: Python=3.1 for Reticulate Environment
Placing Custom Images in a Plot Window--As Custom Data Markers or to Annotate Those Markers