python urllib:构建 url,包括带和不带关键字的参数

python urllib: build urls including parameters with and without keyword

我正在 python 中使用 urllib 构建 grafana links,如下所示:

from urllib.parse import urlencode, urlunsplit

parameters = {
    "parameter1":"value1",
    "parameter2":"value2"
}

query = urlencode(
    query = parameters,
    doseq = True
)

link = urlunsplit((
    "https",
    "my_grafana.com",
    "/graph",
    query,
    ""
))

link 在这种情况下将是 'https://my_grafana.com/graph?parameter1=value1&parameter2=value2'。我现在想添加没有关键字的参数,例如“kiosk”。 link 应该看起来像 'https://my_grafana.com/graph?parameter1=value1&parameter2=value2&kiosk&other_parameter'

作为 urlencode returns 一个带有参数的字符串,我可以像下面的例子一样在我把它交给 urlunsplit:

之前操作这个字符串
no_keyword_parameters = ["kiosk","other_parameter"]
query = "&".join([query, *no_keyword_parameters])

不知道能不能把带关键字的参数和不带关键字的参数直接和urlencode放在一起。我尝试将“kiosk”作为字典条目,以 None 作为内容 ({"kiosk": None}),但它在 url 中包含 None。我给出元组列表而不是参数字典的方法也不成功。

感谢您的帮助。

您所做的似乎很合理,您可以那样做,也可以在您自己的编码函数中对其进行更多形式化,但是 urllib.parse.urlencode 似乎不理解无值参数的概念。如果您查看 implementation(使用 doseq,您会得到与您的问题相关的部分相同的变体):

        for k, v in query:
...
           l.append(k + '=' + v)

即你必须有一个键,值对(解压两个值)并且它们被引用(发生在省略号中)将是一个 str 连接在 = 上。所以即使使用自定义 qoute_via 你也不能真正改变它的功能。

链接的实现是 CPython 提供的,也是 documentation 期望的:key/value 对,因此行为确实如指定/记录的那样:

The resulting string is a series of key=value pairs separated by '&' characters...

Ondrej 所述,urlencode 使用 k + '=' + v 构建查询。
您可以手动添加非值参数:

from urllib.parse import urlencode, urlunsplit, quote_plus

parameters = {"parameter1": "value1", "parameter2": "value2"}
no_value_parameters = ["kiosk", "other_parameter"]
no_value_parameters_quoted = [quote_plus(p) for p in no_value_parameters]

query = urlencode(query=parameters, doseq=True)
link = urlunsplit(("https", "my_grafana.com", "/graph", query, ""))
link = f"{link}&{'&'.join(no_value_parameters_quoted)}"
print(link)

输出:

https://my_grafana.com/graph?parameter1=value1&parameter2=value2&kiosk&other_parameter