解析URL路径时python和ruby之间的不同,哪个有效?
Posted
技术标签:
【中文标题】解析URL路径时python和ruby之间的不同,哪个有效?【英文标题】:different between python and ruby when parsing URL path, which is valid? 【发布时间】:2021-09-21 07:11:16 【问题描述】:我有一个 URL 字符串:
url = "https://foo.bar.com/path/to/aaa.bbb/ccc.ddd;dc_trk_aid=486652617;tfua=;gdpr=;gdpr_consent=?&339286293"
使用 Python 时
from urllib.parse import urlparse
url_obj = urlparse(url)
url_obj.path # `path/to/aaa.bbb/ccc.ddd`
使用红宝石时
url_obj = URI.parse(url)
url_obj.path # `path/to/aaa.bbb/ccc.ddd;dc_trk_aid=486652617;tfua=;gdpr=;gdpr_consent=`
我猜python认为;
不是url路径的一部分,哪一个是“正确的”?
【问题讨论】:
根据 rfc 它应该被允许......也许是 urlparse 的一个错误(但它似乎在url_obj.params
中可用
@JoranBeasley AFAIK ;
被推荐(至少在过去的某个时间点)作为&
的替代品作为查询参数分隔符。这只会在 ?
之后应用,但也许这就是 Python 正在做的事情。
@muistooshort 明白了,我给出的这个示例url是从浏览器中捕获的,我必须解析和使用它,所以我别无选择,只能处理它。
【参考方案1】:
urlparse
在第一个分号后的path
部分为params
:
url_obj.path # '/path/to/aaa.bbb/ccc.ddd'
url_obj.params # 'dc_trk_aid=486652617;tfua=;gdpr=;gdpr_consent='
要复制 Ruby 的行为,请改用 urlsplit
:
这类似于
urlparse()
,但不会从 URL 中拆分参数。如果需要更新的 URL 语法,允许将参数应用于 URL 的 path 部分的每个段(请参阅 RFC 2396),则通常应使用该语法而不是urlparse()
。
from urllib.parse import urlsplit
url_obj = urlsplit(url)
url_obj.path # '/path/to/aaa.bbb/ccc.ddd;dc_trk_aid=486652617;tfua=;gdpr=;gdpr_consent='
【讨论】:
感谢 Amadan,我的问题是我正在将 python 脚本翻译成 ruby 等价物,所以我想我们发现了原始 python 脚本的“错误”并在 ruby 版本中执行正确的行为.至少这有助于解决这个问题。【参考方案2】:Python 的urllib
是错误的。 RFC 3986 Uniform Resource Identifier (URI): Generic Syntax, Section 3.3 Path 明确给出了这个确切的语法作为有效路径的示例[bold强调我的]:
除了层次路径中的点段之外,路径段被通用语法认为是不透明的。生成 URI 的应用程序通常使用段中允许的保留字符来分隔特定于方案或特定于解引用处理程序的子组件。例如,分号 (";") 和等号 ("=") 保留字符通常用于分隔适用于该段的参数和参数值。逗号 (",") 保留字符通常用于类似目的。例如,一个 URI 生产者可能使用诸如“name;v=1.1”之类的片段来指示对“name”的 1.1 版的引用,而另一个可能使用诸如“name,1.1”之类的片段"表示相同。参数类型可以由特定于方案的语义定义,但在大多数情况下,参数的语法特定于 URI 的解引用算法的实现。
您发布的示例 URI 的正确解释如下:
方案 =https
权限 = foo.bar.com
用户信息 = 空
主机 = foo.bar.com
port = 空,从 scheme 派生为 443
路径 = /path/to/aaa.bbb/ccc.ddd;dc_trk_aid=486652617;tfua=;gdpr=;gdpr_consent=
,由以下四个路径段组成:
path
to
aaa.bbb
ccc.ddd;dc_trk_aid=486652617;tfua=;gdpr=;gdpr_consent=
&339286293
片段 = 空
【讨论】:
没有错。urlparse
通过将最后一个路径段的参数(根据引用的 RFC)拆分到其自己的字段中来“提供帮助”。 urllib
中有一个函数不这样做,所以我宁愿说 urlparse
是奇怪的,而不是 urllib
作为一个包是错误的。
感谢您提供的详细信息,至少现在我只是按照 ruby 的解析结果表格并忽略 py 版本以上是关于解析URL路径时python和ruby之间的不同,哪个有效?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Nokogiri xpath 解析时未插入 Ruby 环境变量