#!/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'
如果您想在下载之前获得as URL的内容类型,那么HTTP命令
HEAD
就是为了这个目的。如果您使用HEAD
而不是GET
,那么您将得到与GET
相同的报头,但是没有正文(这意味着您和服务器的开销更小)。在其中一个头应该是
Content-Type
,这将告诉您它是否是一个图像。在如果您想更进一步,您可以从disposition头猜测文件名,如果猜不到,还可以猜测最终重定向URL的基名的扩展名,这是浏览器通常在服务器损坏的情况下显示图像的方式,但这很少需要。在
如果你因为某种原因根本不能进行任何网络请求,你所能做的最好的就是试探性地猜测。如果你只是从一个特定的服务器上抓取,比如维基百科,你可以得到一个URL列表,并尝试找到一个服务器使用的模式——例如,URL的某个部分中的
images
——这可能对许多图像有效,但可能不适用于所有图像,并且可能在下次他们进行重大服务升级时中断,因此您必须继续观察并定期改进你的启发式代码。在HTTP服务器几乎总是在响应
GET
或HEAD
url请求时返回一个Content-Type报头:要处理大量的url,最快的方法是只检索头,而不下载整个文件,并在content-type响应头上检查其mime类型(这里是您必须检查的image mime types列表)。它们都是以图像开始的/所以这就是您要寻找的)。在
例如,使用pycurl(如果您在windows上,可以使用pip或here获得它;对于64位windows,here),类似这样的方法会检查响应头(我不太精通python,所以我建议您搜索如何解析Content-Type头,以便更好地检查图像mime类型,并将其正确地封装在函数中):
您可以发出
head
请求来检查url
的内容类型。头部请求不会下载正文内容。 使用pythonrequests模块的示例:相关问题 更多 >
编程相关推荐