11

我正在尝试通过加入一些动态组件来构建 URL。在我的案例中,我想使用类似os.path.join()BUT 的东西作为 URL。从研究中我发现urlparse.urljoin()做同样的事情。但是,看起来它一次只需要两个参数。

到目前为止,我有以下工作但看起来重复:

    a = urlparse.urljoin(environment, schedule_uri)
    b = urlparse.urljoin(a, str(events_to_hours))
    c = urlparse.urljoin(b, str(events_from_date))
    d = urlparse.urljoin(c, str(api_version))
    e = urlparse.urljoin(d, str(id))
    url = e + '.json'

输出 =http://example.com/schedule/12/20160322/v1/1.json

以上工作,我试图通过这种方式缩短它:

url_join_items = [environment, schedule_uri, str(events_to_hours),
                  str(events_from_date), str(api_version), str(id), ".json"]
new_url = ""
for url_items in url_join_items:
    new_url = urlparse.urljoin(new_url, url_items)

输出:http://example.com/schedule/.json

但是第二个实现不起作用。请建议我如何解决这个问题或更好的方法。

编辑 1:reduce解决方案的输出如下所示(不幸的是): 输出:http://example.com/schedule/.json

4

4 回答 4

20

使用连接

你试过简单吗"/".join(url_join_items)。http 不总是使用正斜杠吗?不过,您可能必须手动设置前缀“https://”和后缀。

就像是:

url = "https://{}.json".format("/".join(url_join_items))

使用 reduce 和 urljoin

这是关于 SO 的一个相关问题,它在一定程度上解释了urljoin. 您的用例似乎不是最合适的。

使用reduceand时urljoin,我不确定它会按照问题的意图进行,这在语义上类似于os.path.join,但对于 url。考虑以下:

from urllib.parse import urljoin
from functools import reduce

parts_1 = ["a","b","c","d"]
parts_2 = ["https://","server.com","somedir","somefile.json"]
parts_3 = ["https://","server.com/","somedir/","somefile.json"]

out1 = reduce(urljoin, parts_1)
print(out1)

d

out2 = reduce(urljoin, parts_2)
print(out2)

https:///somefile.json

out3 = reduce(urljoin, parts_3)
print(out3)

https:///server.com/somedir/somefile.json

请注意,除了 https 前缀后的额外“/”之外,第三个输出可能最接近询问者的意图,除非我们必须完成所有使用分隔符格式化部分的工作。

于 2016-03-23T22:07:33.933 回答
4

怎么样url = reduce(urlparse.urljoin, url_join_items)

于 2016-03-23T22:04:58.030 回答
1

我也需要类似的东西并想出了这个解决方案:

from urllib.parse import urljoin, quote_plus

def multi_urljoin(*parts):
    return urljoin(parts[0], "/".join(quote_plus(part.strip("/"), safe="/") for part in parts[1:]))

print(multi_urljoin("https://server.com", "path/to/some/dir/", "2019", "4", "17", "some_random_string", "image.jpg"))

这打印'https://server.com/path/to/some/dir/2019/4/17/some_random_string/image.jpg'

于 2019-04-17T08:07:18.293 回答
1

这是一个有点傻但可行的解决方案,因为这parts是一个按顺序排列的 URL 部分列表

my_url = '/'.join(parts).replace('//', '/').replace(':/', '://')

我希望replace有一个from选择,但它没有,因此第二个是恢复https://双斜线

好消息是您不必担心零件已经有(或没有)任何斜线

于 2020-08-31T21:58:11.177 回答