Python urlparse无法解析自定义schema的params参数问题
自定义URI使用urlparse解析params的问题与解决
问题现象
使用Python的urllib.parse.urlparse解析URI时,http、ftp这类知名scheme能正确拆分路径后;分隔的参数到params字段:
>>> from urllib.parse import urlparse >>> urlparse("http://some.domain/some/nested/endpoint;param1=value1;param2=othervalue2?query1=val1&query2=val2#fragment") ParseResult(scheme='http', netloc='some.domain', path='/some/nested/endpoint', params='param1=value1;param2=othervalue2', query='query1=val1&query2=val2', fragment='fragment') >>> urlparse("ftp://some.domain/some/nested/endpoint;param1=value1;param2=othervalue2?query1=val1&query2=val2#fragment") ParseResult(scheme='ftp', netloc='some.domain', path='/some/nested/endpoint', params='param1=value1;param2=othervalue2', query='query1=val1&query2=val2', fragment='fragment')
但自定义scheme的解析结果中,params字段为空,参数被合并到path字段:
>>> from urllib.parse import urlparse >>> urlparse("scheme://some.domain/some/nested/endpoint;param1=value1;param2=othervalue2?query1=val1&query2=val2#fragment") ParseResult(scheme='scheme', netloc='some.domain', path='/some/nested/endpoint;param1=value1;param2=othervalue2', params='', query='query1=val1&query2=val2', fragment='fragment')
原因分析
urlparse的解析逻辑依赖scheme的类型:
- http、ftp等分层式URL scheme,遵循RFC 3986定义的分层结构规范,解析器会自动识别路径中
;分隔的参数段,将其拆分到params字段。 - 自定义scheme默认被归类为非分层式,解析器不会处理路径中的
;分隔符,因此参数会被保留在path字段内。
解决方法
1. 注册自定义scheme为分层类型
通过修改urllib.parse.uses_params集合,将自定义scheme加入其中,让解析器按分层规则处理:
from urllib.parse import urlparse, uses_params # 注册自定义scheme uses_params.add('scheme') # 重新解析即可正确拆分params result = urlparse("scheme://some.domain/some/nested/endpoint;param1=value1;param2=othervalue2?query1=val1&query2=val2#fragment") print(result.params) # 输出: param1=value1;param2=othervalue2
2. 手动拆分路径与参数
如果不想修改全局设置,可以手动拆分解析后的path字段,重新构造结果:
from urllib.parse import urlparse result = urlparse("scheme://some.domain/some/nested/endpoint;param1=value1;param2=othervalue2?query1=val1&query2=val2#fragment") if ';' in result.path: path_part, params_part = result.path.split(';', 1) # 替换原结果的path和params字段 corrected_result = result._replace(path=path_part, params=params_part) print(corrected_result.params) # 输出: param1=value1;param2=othervalue2
内容的提问来源于stack exchange,提问作者Konrad Sikorski
相关产品推荐
相关产品推荐

