如何使用`urlparse`检查URL是否有效?

时间:2014-08-12 08:03:59

标签: python urllib2 url-parsing urlparse

在打开URL以读取数据之前,我想检查URL是否有效。

我使用的是urlparse包中的urlparse函数:

if not bool(urlparse.urlparse(url).netloc):
 # do something like: open and read using urllin2

但是,我注意到一些有效的URL被视为已损坏,例如:

url = upload.wikimedia.org/math/8/8/d/88d27d47cea8c88adf93b1881eda318d.png

此网址有效(我可以使用我的浏览器打开它)。

有没有更好的方法来检查网址是否有效?

4 个答案:

答案 0 :(得分:11)

您可以检查网址是否包含该方案:

>>> url = "no.scheme.com/math/12345.png"
>>> parsed_url = urlparse.urlparse(url)
>>> bool(parsed_url.scheme)
False

如果是这种情况,您可以替换该方案并获得真实的有效网址:

>>> parsed_url.geturl()
"no.scheme.com/math/12345.png"
>>> parsed_url = parsed_url._replace(**{"scheme": "http"})
>>> parsed_url.geturl()
'http:///no.scheme.com/math/12345.png'

答案 1 :(得分:3)

TL; DR:实际上你不能。给出的每个答案都已经错过了一个或多个案例。

  1. 字符串 google.com (因为没有方案,因此无效,即使浏览器默认使用http)。 Urlparse将丢失scheme和netloc。所以all([result.scheme, result.netloc, result.path])似乎适用于此案例
  2. 字符串 http://google (由于缺少.com而无效)。 Urlparse将只缺少路径。再次all([result.scheme, result.netloc, result.path])似乎抓住了这个案例
  3. 字符串 http://google.com/ (正确)。 Urlparse将填充scheme,netloc和path。因此,对于这种情况all([result.scheme, result.netloc, result.path])正常工作
  4. 字符串 http://google.com (正确)。 Urlparse将只缺少路径。因此,对于这种情况,all([result.scheme, result.netloc, result.path])似乎给出了假阴性
  5. 因此,从上述情况可以看出,最接近解决方案的是all([result.scheme, result.netloc, result.path])。但这仅适用于url包含路径的情况(即使这是/ path)。即使你试图强制执行一条路径(即urlparse(urljoin(your_url, "/")),你仍然会在案例2中得到误报

    也许更复杂的事情如

    final_url = urlparse(urljoin(your_url, "/"))
    is_correct = (all([final_url.scheme, final_url.netloc, final_url.path]) 
                  and len(final_url.netloc.split(".")) > 1)
    

    也许您还想跳过方案检查,如果没有方案则假设为http。 但即便如此,这也会让你达到一定程度。虽然它涵盖了上述情况,但它并未完全涵盖url包含ip而不是主机名的情况。对于这种情况,您必须验证ip是否是正确的ip。还有更多场景。请参阅https://en.wikipedia.org/wiki/URL以考虑更多案例

答案 2 :(得分:2)

您可以尝试下面的功能,检查解析网址后出现的schemenetlocpath变量。支持Python 2和3。

try:
    # python 3
    from urllib.parse import urlparse
except ImportError:
    from urlparse import urlparse

def url_validator(url):
    try:
        result = urlparse(url)
        return all([result.scheme, result.netloc, result.path])
    except:
        return False

答案 3 :(得分:1)

没有架构的Url实际上是无效的,您的浏览器非常聪明,可以建议使用http://作为架构。检查网址是否没有架构(not re.match(r'^[a-zA-Z]+://', url))并在其中添加http://可能是一个很好的解决方案。