You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 11:17:48