1

我有一个 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路径的一部分,哪一个是“正确的”?

4

2 回答 2

6

urlparsepath在第一个分号之后的部分为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 中拆分参数。urlparse()如果需要更新的 URL 语法,允许将参数应用于 URL 的路径部分的每个段(参见 RFC 2396),通常应该使用此方法。

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='
于 2021-07-12T08:28:40.687 回答
2

Pythonurllib是错误的。RFC 3986统一资源标识符 (URI):通用语法,第 3.3 节路径明确给出了这个确切的语法作为有效路径的示例[粗体强调我的]:

除了层次路径中的点段之外,路径段被通用语法认为是不透明的。生成 URI 的应用程序通常使用段中允许的保留字符来分隔特定于方案或特定于解引用处理程序的子组件。例如,分号 (";") 和等号 ("=") 保留字符通常用于分隔适用于该段的参数和参数值。逗号 (",") 保留字符通常用于类似目的。例如,一个 URI 生产者可能使用诸如“name;v=1.1”之类的段来指示对“name”版本 1.1 的引用,而另一个可能使用诸如“name,1.1”之类的段来表示相同。参数类型可以由特定于方案的语义定义,但在大多数情况下,参数的语法特定于 URI 的解引用算法的实现。

您发布的示例 URI的正确解释如下:

  • 方案=https
  • 权威=foo.bar.com
    • 用户信息= 空
    • 主机=foo.bar.com
    • 端口= 空,从方案派生为443
  • path = /path/to/aaa.bbb/ccc.ddd;dc_trk_aid=486652617;tfua=;gdpr=;gdpr_consent=,由以下四个路径段组成
    1. path
    2. to
    3. aaa.bbb
    4. ccc.ddd;dc_trk_aid=486652617;tfua=;gdpr=;gdpr_consent=
  • 查询=&339286293
  • 片段=空
于 2021-07-12T08:10:54.517 回答