Python:加入多个组件构建一个URL
Python: Join multiple components to build a URL
我正在尝试通过加入一些动态组件来构建 URL。在我的例子中,我想过对 URL 使用 os.path.join()
BUT 之类的东西。通过研究,我发现 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
使用加入
你有没有简单地试过"/".join(url_join_items)
。 http 不是总是使用正斜杠吗?不过,您可能必须手动设置前缀 "https://" 和后缀。
类似于:
url = "https://{}.json".format("/".join(url_join_items))
使用 reduce 和 urljoin
这里有一篇关于 SO 的 related question,它在某种程度上解释了 urljoin
实现背后的想法。您的用例似乎不是最合适的。
当使用 reduce
和 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 前缀后的额外“/”外,第三个输出可能最接近提问者的意图,只是我们必须完成所有使用分隔符格式化部分的工作.
我也需要类似的东西并提出了这个解决方案:
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'
考虑到 parts
是 URL 个按顺序排列的部分的列表,这里有一个有点愚蠢但可行的解决方案
my_url = '/'.join(parts).replace('//', '/').replace(':/', '://')
我希望 replace
有一个 from
选项,但它没有,因此第二个是恢复 https://
双斜线
好处是您不必担心零件已经有(或没有)任何斜线
我正在尝试通过加入一些动态组件来构建 URL。在我的例子中,我想过对 URL 使用 os.path.join()
BUT 之类的东西。通过研究,我发现 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
使用加入
你有没有简单地试过"/".join(url_join_items)
。 http 不是总是使用正斜杠吗?不过,您可能必须手动设置前缀 "https://" 和后缀。
类似于:
url = "https://{}.json".format("/".join(url_join_items))
使用 reduce 和 urljoin
这里有一篇关于 SO 的 related question,它在某种程度上解释了 urljoin
实现背后的想法。您的用例似乎不是最合适的。
当使用 reduce
和 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 前缀后的额外“/”外,第三个输出可能最接近提问者的意图,只是我们必须完成所有使用分隔符格式化部分的工作.
我也需要类似的东西并提出了这个解决方案:
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'
考虑到 parts
是 URL 个按顺序排列的部分的列表,这里有一个有点愚蠢但可行的解决方案
my_url = '/'.join(parts).replace('//', '/').replace(':/', '://')
我希望 replace
有一个 from
选项,但它没有,因此第二个是恢复 https://
双斜线
好处是您不必担心零件已经有(或没有)任何斜线