Handler处理器和自定义opener
来源:互联网 发布:公务员 紧缺职位 知乎 编辑:程序博客网 时间:2024/05/27 20:51
Handler处理器和自定义opener
在我们使用urllib库请求是都是使用urlopen()方法实现的。实际上它的底层是使用HTTPHandler个Opener来实现的。如:urlopen()源码:
global _openerif cafile or capath or cadefault: ... https_handler = HTTPSHandler(context=context) opener = build_opener(https_handler)elif context: https_handler = HTTPSHandler(context=context) opener = build_opener(https_handler)elif _opener is None: _opener = opener = build_opener()else: opener = _openerreturn opener.open(url, data, timeout)
我们采用urlopen()的方式去请求,其实是有些局限性的,比如我们需要打开debug模式,或通过代理模式去请求,就不行了。如果要实现debug模式或代理请求的话,我们需要自己定义Handler和opener。
在urllib库中,给我们提供了一些Handler,如:HTTPHandler,HTTPSHandler,ProxyHandler,BaseHandler,AbstractHTTPHandler,FileHandler,FTPHandler,分别用于处理HTTP,HTTPS,Proxy代理等。
简单的自定义Handler和opener
import urllib.requestdef common_handler(url, headers): """ 通过使用HTTPHandler发送请求 """ # 创建HTTPHandler对象 handlers = urllib.request.HTTPHandler() # 创建一个Opener对象 opener = urllib.request.build_opener(handlers) # 获取一个请求 req = urllib.request.Request(url, headers=headers) # 通过opener请求访问服务器,并返回一个响应对象 resp = opener.open(req) with open('common_handler_baidu.html', 'wb') as f: f.write(resp.read())if __name__ == '__main__': url = 'http://www.baidu.com' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36'} common_handler(url, headers)
HTTPHandler的debug模式
HTTPHandler的debug模式,是通过在HTTPHandler的参数中传入debuglevel=1
,1表示打开debug模式。0表示关闭,默认是0。代码如下:
import urllib.requestdef debug_handler(url, headers): # 给HTTPHandler的构造方法中,添加有个参数,debuglevel=1,表示打开debug模式。 handlers = urllib.request.HTTPHandler(debuglevel=1) opener = urllib.request.build_opener(handlers) req = urllib.request.Request(url, headers=headers) resp = opener.open(req) with open('debug_handler_baidu.html', 'wb') as f: f.write(resp.read())if __name__ == '__main__': url = 'http://www.baidu.com' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36'} debug_handler(url, headers)
在运行的时候,会直接输入log信息。如图:
ProxyHandler的代理模式
在urllib库中,我们使用ProxyHandler来进行代理请求。具体代码如下:
import urllib.requestdef proxy_hander(url, headers): # 通过ProxyHandler来做代理请求,参数是一个dict类型。key是http,value是指ip和端口。 handlers = urllib.request.ProxyHandler({'http': '124.88.67.81:80'}) # ip是网上查找的公共ip,有可能失效,不能访问 opener = urllib.request.build_opener(handlers) req = urllib.request.Request(url, headers=headers) resp = opener.open(req) with open('proxy_handler_baidu.html', 'wb') as f: f.write(resp.read())if __name__ == '__main__': url = 'http://www.baidu.com' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36'} proxy_hander(url, headers)
ProxyBasicAuthHandler代理授权验证
如果我们是使用一个需要授权验证的ip做代理,直接使用ProxyHandler代理会报一个HTTP 407
的错误,如下:
HTTPError: HTTP Error 407: Proxy Authentication Required
遇到上述问题,我们需要ProxyBasicAuthHandler来处理代理请求。除此之外,我们还需要HTTPPasswordMgrWithDefaultRealm构建一个密码的管理对象,保存需要处理的用户名和密码。具体看下面示例:
import urllib.requestdef proxyauth_handler(url, headers): # 代理的ip和端口 server_ip = '192.168.199.107:80' # 在测试是,请更换代理的ip,该ip已失效 # 代理ip的用户名,如 admin user = 'admin' # 代理ip密码,如 admin password = 'admin' # 创建一个密码管理对象 passwordMgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() # 将ip,用户名,密码保存到密码管理器中 # 第一个参数realm是与远程服务器相关的域信息,一般没人管它都是写None passwordMgr.add_password(None, server_ip, user, password) # 获取ProxyBasicAuthHandler对象 handler = urllib.request.ProxyBasicAuthHandler(passwordMgr) # 获取opener对象 opener = urllib.request.build_opener(handler) # 获取请求对象 req = urllib.request.Request(url, headers=headers) # 通过opener请求服务器,获取一个响应对象 resp = opener.open(req) with open('proxyauth_handler_baidu.html', 'wb') as f: f.write(resp.read())if __name__ == '__main__': url = 'http://www.baidu.com' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36'} auth_proxy_handler(url, headers)
HTTPBasicAuthHandler处理器(web客户端授权)
有些web服务器在访问时,需要进行用户身份验证,爬虫直接访问会报出HTTP 401
错误,表示访问身份没有授权。
HTTPError: HTTP Eeeor 401: Unauthorized
对于这种情况,我们可以通过HTTPBasicAuthHandler处理器来处理。
HTTPBasicAuthHandler
处理器和ProxyBasicAuthHandler
处理器的用法是一样的,也是通过ip(或url),用户名,密码,通过密码管理对象保存,通过HTTPBasicAuthHandler
返回opener对象。
具体代码如下:
import urllib.requestdef httpauth_handler(url, headers): # 授权账户用户名 user = 'admin' # 授权账户密码 password = 'admin' # 获取密码管理者对象 passwordMgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() # 将密码保存到密码管理者 passwordMgr.add_password(None, url, user, password) # 将密码管理者传给HTTPBasicAuthHandler处理器处理,返回一个处理器对象 handler = urllib.request.HTTPBasicAuthHandler(passwordMgr) # 传入handler,构建一个opener对象 opener = urllib.request.build_opener(handler) # 获取一个请求对象 req = urllib.request.Request(url, headers=headers) # 通过opener请求服务器,获取响应对象 resp = opener.open(req) # 将响应对象返回的是数据读取到文件 with open('httpauth_handler.html', 'wb') as f: f.write(resp.read())if __name__ == '__main__': url = 'http://www.baidu.com' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36'} httpauth_handler(url, headers)
备注:如果我们急需要web客户端验证,有需要代理,那怎么办。实际上build_open()
方法,可以传递多个handler对象。实现多个handler的处理需要。
- Handler处理器 和 自定义Opener
- Handler处理器和自定义opener
- Python爬虫-Handler处理器和自定义Opener
- Python爬虫Handler处理器 和 自定义Opener系列之四
- python爬虫opener和handler
- urllib2自定义opener详解
- urllib2自定义opener详解
- urllib2自定义opener
- urllib2自定义opener详解
- urllib2自定义opener详解
- urllib2自定义opener详解
- [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
- [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
- [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
- [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
- 网络爬虫(四)Opener与Handler的介绍和实例应用
- [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
- [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
- GAN与NLP的结合相关资料汇总与总结
- Unable to compile class for JSP 问题解决方法
- 论文:Deeplab_v1
- 30.Nginx HTTP之读取处理请求头函数ngx_http_process_request_headers
- Gradle资源汇总
- Handler处理器和自定义opener
- Hibernate学习之单向多对一映射
- 1019. 数字黑洞
- c语言基础(二)
- SSM框架访问webapp下其他文件夹出现404错误
- Docker Swarm 中最重要的概念- 每天5分钟玩转 Docker 容器技术(94)
- sessionid为什么关闭浏览器消失
- Tensorflow 入门 2
- 多线程基础学习九:练习-多线程获取不重复的随机数字