httpx中URL对象将%20转换为+的问题及解决方法咨询
httpx URL对象中%20被转为+的解决方法
问题描述
使用httpx的URL对象时,原始URL中的%20(空格的URL编码)在调用copy_merge_params后会被转为+。示例代码:
from httpx import URL url = 'http://www.example.com?param=a%20b' url_obj = URL(url) url_obj = url_obj.copy_merge_params(params={}) print(str(url_obj)) # 输出: http://www.example.com?param=a+b
经排查,这是因为QueryParams.__str__方法默认调用无额外参数的urlencode(),而urlencode默认使用quote_plus将空格转为+。
解决方法
除了手动处理URL外,有两种更优雅的方案:
1. 自定义QueryParams子类
继承httpx.QueryParams并重写__str__方法,指定quote_via=urllib.parse.quote,让空格编码为%20:
import urllib.parse from httpx import QueryParams, URL class SpacePreservingQueryParams(QueryParams): def __str__(self) -> str: return urllib.parse.urlencode( self._items, doseq=True, quote_via=urllib.parse.quote ) # 使用示例 url = 'http://www.example.com?param=a%20b' url_obj = URL(url) # 合并参数后替换为自定义QueryParams url_obj = url_obj.copy_merge_params(params={}) url_obj = url_obj.replace(query=SpacePreservingQueryParams(url_obj.query)) print(str(url_obj)) # 输出: http://www.example.com?param=a%20b
2. 全局修改QueryParams的字符串序列化行为
如果你的项目中所有请求都需要保留%20而非+,可以直接修改httpx.QueryParams的默认__str__方法(注意:这会影响全局所有使用QueryParams的场景):
import urllib.parse import httpx # 保存原始方法(可选,用于后续恢复) original_query_str = httpx.QueryParams.__str__ def custom_query_str(self): return urllib.parse.urlencode( self._items, doseq=True, quote_via=urllib.parse.quote ) # 替换默认方法 httpx.QueryParams.__str__ = custom_query_str # 原示例代码直接生效 url = 'http://www.example.com?param=a%20b' url_obj = httpx.URL(url) url_obj = url_obj.copy_merge_params(params={}) print(str(url_obj)) # 输出: http://www.example.com?param=a%20b
内容的提问来源于stack exchange,提问作者aikipooh
相关产品推荐
相关产品推荐

