【问题标题】:How to join absolute and relative urls?如何加入绝对和相对网址?
【发布时间】:2012-01-03 16:01:37
【问题描述】:

我有两个网址:

url1 = "http://127.0.0.1/test1/test2/test3/test5.xml"
url2 = "../../test4/test6.xml"

如何获得 url2 的绝对网址?

【问题讨论】:

标签: python url


【解决方案1】:

您可以使用reduce 以更简洁的方式实现 Shikhar 的方法。

>>> import urllib.parse
>>> from functools import reduce
>>> reduce(urllib.parse.urljoin, ["http://moc.com/", "path1/", "path2/", "path3/"])
'http://moc.com/path1/path2/path3/'

请注意,使用此方法,每个片段都应该有尾部正斜杠,没有前导正斜杠,以表明它是一个正在连接的路径片段。

这更正确/信息更丰富,告诉您path1/ 是 URI 路径片段,而不是完整路径(例如 /path1/)或未知路径(例如 path1)。未知数也可以是,但它们会作为完整路径处理。

如果您需要将/ 添加到缺少它的片段中,您可以这样做:

uri = uri if uri.endswith("/") else f"{uri}/"

要了解有关 URI 解析的更多信息,Wikipedia 提供了一些很好的示例。

更新

  • 刚刚注意到 Peter Perron 在 Shikhar 的回答中评论了 reduce,但我将把它留在这里,然后演示它是如何完成的。

  • 更新的维基百科网址

【讨论】:

    【解决方案2】:

    对于python 3.0+,加入url的正确方法是:

    from urllib.parse import urljoin
    urljoin('https://10.66.0.200/', '/api/org')
    # output : 'https://10.66.0.200/api/org'
    

    【讨论】:

    • 这仅限于加入两个路​​径组件。多了就不好用了。
    【解决方案3】:

    如果您的相对路径由多个部分组成,则必须分别加入它们,因为urljoin 将替换相对路径,而不是加入它。最简单的方法是使用posixpath

    >>> import urllib.parse
    >>> import posixpath
    >>> url1 = "http://127.0.0.1"
    >>> url2 = "test1"
    >>> url3 = "test2"
    >>> url4 = "test3"
    >>> url5 = "test5.xml"
    >>> url_path = posixpath.join(url2, url3, url4, url5)
    >>> urllib.parse.urljoin(url1, url_path)
    'http://127.0.0.1/test1/test2/test3/test5.xml'
    

    另请参阅:How to join components of a path when you are constructing a URL in Python

    【讨论】:

      【解决方案4】:

      你应该使用urlparse.urljoin

      >>> import urlparse
      >>> urlparse.urljoin(url1, url2)
      'http://127.0.0.1/test1/test4/test6.xml'
      

      使用 Python 3(urlparse is renamed to urllib.parse)你可以use it as follow

      >>> import urllib.parse
      >>> urllib.parse.urljoin(url1, url2)
      'http://127.0.0.1/test1/test4/test6.xml'
      

      【讨论】:

      • 我们如何将urljoin 与 3 个或模式参数一起使用,或者您为此推荐哪个库?
      • @mesuutt 尝试创建一个循环并使用之前加入的 URL 加入每个部分。
      • @CédricJulien:一个简单的循环将不起作用,因为任何带有前导 / 的路径都将“重置”并返回方案 + netloc + lasturl:urlparse.urljoin('http://www.a.com/b/c/d', '/e') => 'http://www.a.com/e'
      • 如果使用urljoin,就有问题了。例如urljoin('http://www.a.com/', '../../b/c.png'),结果是'http://www.a.com/../../b/c.png',但不是http://www.a.com/b/c.png。那么,有没有什么方法可以得到http://www.a.com/b/c.png呢?
      • 链接到 Python 3 文档指向 Python 2 文档,它需要在答案中更新,它是 docs.python.org/3.6/library/…
      【解决方案5】:
      es = ['http://127.0.0.1', 'test1', 'test4', 'test6.xml']
      base = ''
      map(lambda e: urlparse.urljoin(base, e), es)
      

      【讨论】:

      • 支持值列表的好方法。您可以通过使用 reduce 来消除您的副作用(您的“基础”变量)。 reduce(lambda a, b: urlparse.urljoin(a, b), es) map 是 list[n] - to -> list[n] reduce 是 list[n] - to -> a calculated value
      【解决方案6】:
      >>> from urlparse import urljoin
      >>> url1 = "http://www.youtube.com/user/khanacademy"
      >>> url2 = "/user/khanacademy"
      >>> urljoin(url1, url2)
      'http://www.youtube.com/user/khanacademy'
      

      简单。

      【讨论】:

        猜你喜欢
        • 2010-10-28
        • 1970-01-01
        • 1970-01-01
        • 2019-12-03
        • 2019-06-25
        • 1970-01-01
        • 2012-05-27
        • 2015-02-15
        • 1970-01-01
        相关资源
        最近更新 更多