【问题标题】:check if a URL to an image is up and exists in Python检查图像的 URL 是否已启动并在 Python 中存在
【发布时间】:2012-05-19 14:41:42
【问题描述】:

我正在做一个网站。我想从服务器检查用户提交的链接是否真的存在。

【问题讨论】:

    标签: python http url


    【解决方案1】:

    这是适用于我的应用程序的最佳方法,也是基于以前的 cmets:

    def is_url_image(image_url):
       image_formats = ("image/png", "image/jpeg", "image/jpg")
       r = requests.head(image_url)
       if r.headers["content-type"] in image_formats:
          return True
       return False
    

    【讨论】:

    • 通过请求标头猜测 MIME 类型是一种更好的方法,但我会提防使用 HEAD 请求,我听说有些网站无法正常运行,而GET 请求可能会更好。虽然,我引用的案例与 content-size 标头有关,而不是 content-type 标头,所以谁知道呢。
    • 对于两个不同的 URL,一个是图片,一个是非图片,r.headers["content-type"] = "text/html; charset=iso-8859-1"。即不管怎样,这个函数都会返回 False。深入探讨,原因似乎是我的“图像” URL 实际上重定向到存在图像的新 URL,这在浏览器和下载时是无缝的,但是如果您手动跟踪重定向,标题只会作为图像返回找到图像“真正”存在的“最终”URL。使用该 URL,例程返回 True。所以...谨慎使用这个例程:它返回的 False 超出了人们可能认为必要的范围。
    【解决方案2】:

    这是一种快速的方法:

    它并没有真正验证它是否真的是一个图像文件,它只是根据文件扩展名进行猜测,然后检查 url 是否存在。如果您确实需要验证从 url 返回的数据实际上是图像(出于安全原因),那么此解决方案将不起作用。

    import mimetypes, urllib2
    
    def is_url_image(url):    
        mimetype,encoding = mimetypes.guess_type(url)
        return (mimetype and mimetype.startswith('image'))
    
    def check_url(url):
        """Returns True if the url returns a response code between 200-300,
           otherwise return False.
        """
        try:
            headers = {
                "Range": "bytes=0-10",
                "User-Agent": "MyTestAgent",
                "Accept": "*/*"
            }
    
            req = urllib2.Request(url, headers=headers)
            response = urllib2.urlopen(req)
            return response.code in range(200, 209)
        except Exception:
            return False
    
    def is_image_and_ready(url):
        return is_url_image(url) and check_url(url)
    

    【讨论】:

    • 一个 HEAD 请求也可以做到。
    • 我发现支持 Range 标头的站点/服务器比响应 HEAD 请求的站点/服务器多,即使这就是头请求的用途。
    • 很好奇。范围0-10 是任意的吗?例如,您能否请求0-0?这样做似乎是有效的:w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.1
    • 我认为导入语句应该说'mimetypes'。
    • 如果给定 URL 中有参数:import mimetypes def is_url_image(url): mimetype,encoding = mimetypes.guess_type(url.split("?")[0]) return (mimetype and mimetype.startswith('image'))
    【解决方案3】:

    你可以读取http请求的头部,它包含一些像content-type这样的元数据。

    在 python 3 上:

    from urllib.request import urlopen
    image_formats = ("image/png", "image/jpeg", "image/gif")
    url = "http://localhost/img.png"
    site = urlopen(url)
    meta = site.info()  # get header of the http request
    if meta["content-type"] in image_formats:  # check if the content-type is a image
        print("it is an image")
    

    您还可以获得其他信息,例如图像的大小等。好消息是它不会下载图像。如果标头说它是图像而不是,它可能会失败,但如果图像通过第一个过滤器,您仍然可以进行最后检查并下载图像。

    【讨论】:

      【解决方案4】:

      看看imghdr

      下面是一些示例代码:

      import imghdr
      import httplib
      import cStringIO
      
      conn = httplib.HTTPConnection('www.ovguide.com', timeout=60)
      path = '/img/global/ovg_logo.png'
      conn.request('GET', path)
      r1 = conn.getresponse()
      
      image_file_obj = cStringIO.StringIO(r1.read())
      what_type = imghdr.what(image_file_obj)
      
      print what_type
      

      这应该返回“png”。如果不是图像,它将返回 None

      希望有帮助!

      -布莱克

      【讨论】:

      • 如果你绝对想确定它是一个图像,这是要走的路,但它的代价是首先检索整个图像文件
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      • 2019-11-18
      • 1970-01-01
      • 2011-01-29
      相关资源
      最近更新 更多