米扑代理官方博客,在编写代理使用示例的过程中,发现访问未经验证的https网站时,会抛出异常:

Traceback (most recent call last):
  File "/Users/homer/Documents/workspace/MimvpProxyDemo/Python2/mimvp-proxy-python2.py", line 89, in <module>
    test_http(proxy_https, mimvp_url2)    
  File "/Users/homer/Documents/workspace/MimvpProxyDemo/Python2/mimvp-proxy-python2.py", line 42, in test_http
    f = opener.open(mimvp_url, timeout=30)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
    response = self._open(req, data)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
    '_open', req)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
    result = func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
    context=self._context)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1197, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>

 

上面异常信息的核心提示为:

urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>

 

操作系统: Mac OS X 

Python 版本:

$ python 
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 12:39:47) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin

 

问题的原因是 “SSL: CERTIFICATE_VERIFY_FAILED”

Python 升级到 2.7.9 之后引入了一个新特性,当使用urllib.urlopen打开一个 https 链接时,会验证一次 SSL 证书

而当目标网站使用的是自签名的证书时就会抛出一个 urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)> 的错误消息,详细信息可以在这里查看(https://www.python.org/dev/peps/pep-0476/

 

解决方案包括下列两种方式:

方式1. 使用ssl创建未经验证的上下文,在urlopen中传入上下文参数

import ssl
import urllib2

context = ssl._create_unverified_context()
print urllib2.urlopen("https://proxy.mimvp.com", context=context).read()

 

方式2. 全局取消证书验证

import ssl
import urllib2

context = ssl._create_unverified_context()
print urllib2.urlopen("https:/proxy.mimvp.com", context=context).read()

 

至此,问题圆满解决!