如何从程序上区分普通url和图像url

2024-03-28 20:54:21 发布

您现在位置:Python中文网/ 问答频道 /正文

3条回答

如果您想在下载之前获得as URL的内容类型,那么HTTP命令HEAD就是为了这个目的。如果您使用HEAD而不是GET,那么您将得到与GET相同的报头,但是没有正文(这意味着您和服务器的开销更小)。在

其中一个头应该是Content-Type,这将告诉您它是否是一个图像。在

如果您想更进一步,您可以从disposition头猜测文件名,如果猜不到,还可以猜测最终重定向URL的基名的扩展名,这是浏览器通常在服务器损坏的情况下显示图像的方式,但这很少需要。在

如果你因为某种原因根本不能进行任何网络请求,你所能做的最好的就是试探性地猜测。如果你只是从一个特定的服务器上抓取,比如维基百科,你可以得到一个URL列表,并尝试找到一个服务器使用的模式——例如,URL的某个部分中的images——这可能对许多图像有效,但可能不适用于所有图像,并且可能在下次他们进行重大服务升级时中断,因此您必须继续观察并定期改进你的启发式代码。在

HTTP服务器几乎总是在响应GETHEADurl请求时返回一个Content-Type报头:

enter image description here

要处理大量的url,最快的方法是只检索头,而不下载整个文件,并在content-type响应头上检查其mime类型(这里是您必须检查的image mime types列表)。它们都是以图像开始的/所以这就是您要寻找的)。在

例如,使用pycurl(如果您在windows上,可以使用pip或here获得它;对于64位windows,here),类似这样的方法会检查响应头(我不太精通python,所以我建议您搜索如何解析Content-Type头,以便更好地检查图像mime类型,并将其正确地封装在函数中):

#!/usr/bin/python
import pycurl
from StringIO import StringIO
import re

def check_image(url):

    headers = StringIO()

    c = pycurl.Curl()
    c.setopt(c.URL, url)
    c.setopt(c.HEADER, 1)
    c.setopt(pycurl.SSL_VERIFYPEER, 0)
    c.setopt(pycurl.SSL_VERIFYHOST, 0) # do not verify ssl certificate
    c.setopt(c.NOBODY, 1) # header only, no body
    c.setopt(c.HEADERFUNCTION, headers.write)
    c.setopt(pycurl.WRITEFUNCTION, lambda x: None)
    c.perform()
    c.close()
    a = re.compile("^.*?Content-Type:( )*image/.*?$", re.IGNORECASE | re.MULTILINE | re.DOTALL)
    if a.match(headers.getvalue()) is None:
        return False
    else:
        return True

if check_image('http://www.wikipedia.org/') is False:
    print 'The resource in http://www.wikipedia.org/ is not an image'

if check_image('https://encrypted-tbn1.gstatic.com/images?q=tbn%3AANd9GcTwC6cNpAen5dgGgTmmH2SG75xhvTN-oRliaOgG-3meNQVm-GdpUu7SQX5wpA') is True:
    print 'The resource in https://encrypted-tbn1.gstatic.com/images?q=tbn%3AANd9GcTwC6cNpAen5dgGgTmmH2SG75xhvTN-oRliaOgG-3meNQVm-GdpUu7SQX5wpA is an image'

您可以发出head请求来检查url的内容类型。头部请求不会下载正文内容。 使用pythonrequests模块的示例:

>>> import requests
>>> url = "https://encrypted-tbn1.gstatic.com/images?q=tbn%3AANd9GcTwC6cNpAen5dgGgTmmH2SG75xhvTN-oRliaOgG-3meNQVm-GdpUu7SQX5wpA"
>>> h = requests.head(url)
>>> print h.headers.get('content-type')
image/jpeg

相关问题 更多 >