【问题标题】:urlparse fails with simple urlurlparse 以简单的 url 失败
【发布时间】:2018-11-03 02:05:00
【问题描述】:

这个简单的代码让urlparse 变得疯狂,它没有正确获取主机名,而是将其设置为None

from urllib.parse import urlparse
parsed = urlparse("google.com/foo?bar=8")
print(parsed.hostname)

我错过了什么吗?

【问题讨论】:

    标签: python python-3.x urlparse


    【解决方案1】:

    只是为了给 Muadh 的回答添加更多背景信息。使用 urlparse 查看这两个变体的输出:

    >>> parsed = urlparse("google.com/foo?bar=8")
    >>> parsed
    ParseResult(scheme='', 
                netloc='', 
                path='google.com/foo', 
                params='', 
                query='bar=8', 
                fragment='')
    

    并指定完整路径

    >>> parsed = urlparse("http://google.com/foo?bar=8")
    >>> parsed
    ParseResult(scheme='http', 
                netloc='google.com', 
                path='/foo', 
                params='', 
                query='bar=8', 
                fragment='')
    

    【讨论】:

      【解决方案2】:

      google.com/foo?bar=8 是一个相对 URL,也就是一个带有“查询”的“路径”。也许您将google.com 视为主机名,但它不一定是(python 怎么知道?)

      URL 由协议或方案(“https:”、“ftp:”等)、主机(“//example.com”)、路径、查询、片段组成。

      所以 urlparse 是最好的猜测,对协议和主机返回 None。

      【讨论】:

        【解决方案3】:

        根据https://www.rfc-editor.org/rfc/rfc1738#section-2.1

        方案名称由一系列字符组成。小写 字母“a”--“z”、数字和字符加号(“+”)、句点(“.”)、 和连字符(“-”)是允许的。为了弹性,程序解释 URL 应将大写字母视为等同于小写 方案名称(例如,允许“HTTP”和“http”)。

        使用之前答案中给出的建议,我编写了这个辅助函数,可以用来代替urllib.parse.urlparse()

        #!/usr/bin/env python3
        import re
        import urllib.parse
        
        def urlparse(address):
            if not re.search(r'^[A-Za-z0-9+.\-]+://', address):
                address = 'tcp://{0}'.format(address)
            return urllib.parse.urlparse(address)
        
        url = urlparse('localhost:1234')
        print(url.hostname, url.port)
        

        此函数的先前版本称为urllib.parse.urlparse(address),如果找不到,则添加“tcp”方案;但是,如果您将用户名传递给“user:pass@localhost:1234”之类的内容,则会将用户名解释为方案。

        【讨论】:

          【解决方案4】:

          要使其正常工作,您必须包含协议标识符 (http://)。这对我有用:

          parsed = urlparse("https://www.google.com/foo?bar=8")
          print(parsed.hostname)
          

          这里的输出是:www.google.com(这似乎是预期的)。更多关于如何使用urlparsehere可以阅读。

          希望对你有所帮助!

          【讨论】:

          • 是的,我知道这可行,但如果我有一个未指定架构的列表怎么办?其实他们不这样做并不奇怪
          • 您指向urlparse 的链接引用了python2。 urlparse 在 python3 中的导入方式不同
          • 在这种情况下,我会检查它是否有协议标识符,如果没有,则在解析之前将其添加到字符串中。
          • @ScottMcC 啊,谢谢你看到这个,我修复了链接。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-17
          • 2019-03-07
          • 2020-10-29
          • 2022-01-19
          • 2015-01-13
          相关资源
          最近更新 更多