我有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的解决方法,它可以解决权限问题,而不会影响安全性?
答案 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/')
有关错误检查的相同建议适用。