如何防止python请求百分比编码我的URL?

Sat*_*Rai 28 python url percent-encoding python-requests

我正在尝试使用python中的requests.get()获取以下格式的URL:

http://api.example.com/export/?format=json&key=site:dummy+type:example+group:wheel

#!/usr/local/bin/python

import requests

print(requests.__versiom__)
url = 'http://api.example.com/export/'
payload = {'format': 'json', 'key': 'site:dummy+type:example+group:wheel'}
r = requests.get(url, params=payload)
print(r.url)
Run Code Online (Sandbox Code Playgroud)

但是,URL的编码百分比,我没有得到预期的响应.

2.2.1
http://api.example.com/export/?key=site%3Adummy%2Btype%3Aexample%2Bgroup%3Awheel&format=json
Run Code Online (Sandbox Code Playgroud)

如果我直接传递URL,这是有效的:

url = http://api.example.com/export/?format=json&key=site:dummy+type:example+group:wheel
r = requests.get(url)
Run Code Online (Sandbox Code Playgroud)

有没有办法以原始形式传递参数 - 没有百分比编码?

谢谢!

fur*_*ras 36

这不是一个好的解决方案,但您可以使用string:

r = requests.get(url, params='format=json&key=site:dummy+type:example+group:wheel')
Run Code Online (Sandbox Code Playgroud)

BTW:

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)
Run Code Online (Sandbox Code Playgroud)


Ken*_*itz 10

按照设计,解决方案是直接传递URL.

  • 不,这是行不通的,即使你直接传递 URL,最新版本的“requests”也会对字符进行编码。 (6认同)
  • 我发现@Darkstar的这个旧评论很有趣,因为他回答的答案是"请求"的作者. (4认同)

小智 10

如果其他人在将来遇到此问题,您可以继承requestsSession,覆盖send方法,并更改原始URL,以修复百分比编码等.以下更正是受欢迎的.

import requests, urllib

class NoQuotedCommasSession(requests.Session):
    def send(self, *a, **kw):
        # a[0] is prepared request
        a[0].url = a[0].url.replace(urllib.quote(","), ",")
        return requests.Session.send(self, *a, **kw)

s = NoQuotedCommasSession()
s.get("http://somesite.com/an,url,with,commas,that,won't,be,encoded.")
Run Code Online (Sandbox Code Playgroud)

  • 在现代版本的请求中,您实际上还必须修补“urllib3”;它执行自己的编码。`requests.urllib3.util.url.PATH_CHARS.add(',')`。这开始进入“比它可能值得的更黑客”的领域,但如果你_真的_需要它......这里就是 (2认同)

kuj*_*ist 7

上面的答案对我不起作用。

我试图在参数包含管道的情况下执行 get 请求,但 python 请求也会对管道进行百分比编码。所以我改用了 urlopen:

# python3
from urllib.request import urlopen

base_url = 'http://www.example.com/search?'
query = 'date_range=2017-01-01|2017-03-01'
url = base_url + query

response = urlopen(url)
data = response.read()
# response data valid

print(response.url)
# output: 'http://www.example.com/search?date_range=2017-01-01|2017-03-01'
Run Code Online (Sandbox Code Playgroud)


小智 5

从 requests 版本 2.26 开始,上述所有解决方案似乎不再起作用。GitHub 存储库中建议的解决方案似乎是使用PreparedRequest 进行解决。

以下内容对我有用。确保 URL 可解析,因此不要使用“this-is-not-a-domain.com”。

import requests

base_url = 'https://www.example.com/search'
query = '?format=json&key=site:dummy+type:example+group:wheel'

s = requests.Session()
req = requests.Request('GET', base_url)
p = req.prepare()
p.url += query
resp = s.send(p)
print(resp.request.url)
Run Code Online (Sandbox Code Playgroud)

来源:https ://github.com/psf/requests/issues/5964#issuecomment-949013046