使用带有urllib2的certifi模块?

时间:2015-11-16 22:26:24

标签: python urllib2

我有trouble downloading https pages with the urllib2 module,这似乎是因为urllib2无法访问系统的证书存储区。

要解决此问题,一种可能的解决方案是使用certifi模块下载带pycurl的https网页。以下是这样做的一个例子:

def download_web_page_with_curl(url_website):
    from pycurl import Curl, CAINFO, URL
    from certifi import where
    from cStringIO import StringIO

    response = StringIO()
    curl = Curl()
    curl.setopt(CAINFO, where())
    curl.setopt(URL, url_website)
    curl.setopt(curl.WRITEFUNCTION, response.write)
    curl.perform()
    curl.close()
    return response.getvalue()

有没有办法使用带有urllib2的certifi(以与上面的pycurl示例相似的方式),这将允许我下载https网站?或者,是否有另一个可行的基于urllib2的解决方法,它可以解决权限问题,而不会影响安全性?

2 个答案:

答案 0 :(得分:2)

扩展评论以使用requests(基于urllib3构建):

def download_web_page_with_requests(url_website):
    import requests

    r = requests.get(url_website)
    return r.text

这比其他任何事情都容易得多,并且可以独立于平台自己的证书列表正确处理SSL验证。如果找到certifi,请求将自动使用它。如果没有,它会无声地回退到更有限的,可能更旧的内置根证书集。如果确保使用的证书对您很重要,您可以这样做:

r = requests.get(url_website, verify=certifi.where())

请注意,上面的代码不会执行您应该执行的错误检查。所以我要指出,requests.get()可以为无效的ULR,无法访问的站点,通信错误和失败的认证验证抛出许多例外,因此您应该准备好捕获并处理这些异常。如果它成功与服务器通信,但服务器返回非OK状态代码(例如对于不存在的页面),则不会抛出异常,因此您还需要检查该r。 STATUS_CODE == 200。

答案 1 :(得分:2)

建议根据我的其他答案使用请求。但是,要回答关于如何使用urllib2执行此操作的原始问题:

import urllib2
import certifi
def download_web_page_with_urllib2(url_website):
    t = urllib2.urlopen(url_website, cafile=certifi.where())
    return t.read()
text = download_web_page_with_urllib2('https://www.google.com/')

有关错误检查的相同建议适用。