前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >二、urllib进阶

二、urllib进阶

作者头像
酱紫安
发布2018-04-16 15:52:15
6010
发布2018-04-16 15:52:15
举报
文章被收录于专栏:python学习路python学习路

Handler处理器 和 自定义Opener

  • opener是 urllib.request.OpenerDirector 的实例,我们之前一直都在使用的urlopen,它是一个特殊的opener(也就是模块帮我们构建好的)。
  • 但是基本的urlopen()方法不支持代理、cookie等其他的HTTP/HTTPS高级功能。所以要支持这些功能:

   使用相关的 Handler处理器 来创建特定功能的处理器对象;

      然后通过 urllib.request.build_opener()方法使用这些处理器对象,创建自定义opener对象;

   使用自定义的opener对象,调用open()方法发送请求。

  • 如果程序里所有的请求都使用自定义的opener,可以使用urllib.resquest.install_opener() 将自定义的 opener 对象 定义为 全局opener,表示如果之后凡是调用urlopen,都将使用这个opener(根据自己的需求来选择)

简单的自定义opener()

代码语言:javascript
复制
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from urllib import request
 5 
 6 # 构建一个HTTPHandler处理器对象,支持处理HTTP的请求
 7 #http_handler = request.HTTPHandler()
 8 
 9 # 在HTTPHandler增加参数"debuglevel=1"将会自动打开Debug log 模式,
10 # 程序在执行的时候会打印收发包的信息
11 http_handler = request.HTTPHandler(debuglevel=1)
12 
13 # 调用build_opener()方法构建一个自定义的opener对象,参数是构建的处理器对象
14 opener = request.build_opener(http_handler)
15 
16 request = request.Request("http://www.baidu.com/")
17 
18 response = opener.open(request)
19 
20 print(response.read())

这种方式发送请求得到的结果,和使用urllib2.urlopen()发送HTTP/HTTPS请求得到的结果是一样的。

如果在 HTTPHandler()增加 debuglevel=1参数,还会将 Debug Log 打开,这样程序在执行的时候,会把收包和发包的报头在屏幕上自动打印出来,方便调试,有时可以省去抓包的工作。

ProxyHandler处理器(代理设置)

使用代理IP,这是爬虫/反爬虫的第二大招,通常也是最好用的。

很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,它会禁止这个IP的访问。

所以我们可以设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取。

urllib.request中通过ProxyHandler来设置使用代理服务器,下面代码说明如何使用自定义opener来使用代理:

代码语言:javascript
复制
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from urllib import request
 5 
 6 # 代理开关,表示是否启用代理
 7 proxyswitch = False
 8 
 9 
10 # 构建一个Handler处理器对象,参数是一个字典类型,包括代理类型和代理服务器IP+PROT 免费代理网上搜
11 #开放代理
12 httpproxy_handler = request.ProxyHandler({"http" : "124.88.67.54:80"})
13 
14 
15 #私密代理 账号密码拼接
16 #  httpproxy_handler = request.ProxyHandler({'http':账号':'密码@'IP':'port'})
17 
18 
19 # 构建了一个没有代理的处理器对象
20 nullproxy_handler = request.ProxyHandler({})
21 
22 if proxyswitch:
23     opener = request.build_opener(httpproxy_handler)
24 else:
25     opener = request.build_opener(nullproxy_handler)
26 
27 # 构建了一个全局的opener,之后所有的请求都可以用urlopen()方式去发送,也附带Handler的功能
28 request.install_opener(opener)
29 
30 requests = request.Request("http://www.baidu.com/")
31 response = request.urlopen(requests)
32 
33 #print response.read().decode("gbk")
34 print (response.read().decode('utf8'))
35 '''
36 字节--decode(解码)--字符串(unicode)
37 '''

但是,这些免费开放代理一般会有很多人都在使用,而且代理有寿命短,速度慢,匿名度不高,HTTP/HTTPS支持不稳定等缺点。

所以,专业爬虫工程师或爬虫公司会使用高品质的私密代理,这些代理通常需要找专门的代理供应商购买,再通过用户名/密码授权使用。

HTTPPasswordMgrWithDefaultRealm()

HTTPPasswordMgrWithDefaultRealm()类将创建一个密码管理对象,用来保存 HTTP 请求相关的用户名和密码,主要应用两个场景:

  1. 验证代理授权的用户名和密码 (ProxyBasicAuthHandler())
  2. 验证Web客户端的的用户名和密码 (HTTPBasicAuthHandler())

ProxyBasicAuthHandler(代理授权验证)

如果我们使用之前的代码来使用私密代理,会报 HTTP 407 错误,表示代理没有通过身份验证:

urllib2.HTTPError: HTTP Error 407: Proxy Authentication Required

所以我们需要改写代码,通过:

  • HTTPPasswordMgrWithDefaultRealm():来保存私密代理的用户密码
  • ProxyBasicAuthHandler():来处理代理的身份验证。
代码语言:javascript
复制
 1 import urllib.request
 2 
 3 # 用户名
 4 user = ""
 5 # 密码
 6 passwd = ""
 7 # Web服务器 IP
 8 webserver = ""
 9 
10 # 1. 构建一个密码管理对象,用来保存需要处理的用户名和密码
11 passwdmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
12 
13 # 2. 添加账户信息,第一个参数realm是与远程服务器相关的域信息,一般没人管它都是写None,后面三个参数分别是 Web服务器、用户名、密码
14 passwdmgr.add_password(None, webserver, user, passwd)
15 
16 # 3. 构建一个HTTP基础用户名/密码验证的HTTPBasicAuthHandler处理器对象,参数是创建的密码管理对象
17 httpauth_handler = urllib.request.HTTPBasicAuthHandler(passwdmgr)
18 
19 # 4. 通过 build_opener()方法使用这些代理Handler对象,创建自定义opener对象,参数包括构建的 proxy_handler
20 opener = urllib.request.build_opener(httpauth_handler)
21 
22 # 5. 可以选择通过install_opener()方法定义opener为全局opener
23 urllib.request.install_opener(opener)
24 
25 # 6. 构建 Request对象
26 request = urllib.request.Request("http://")
27 
28 # 7. 定义opener为全局opener后,可直接使用urlopen()发送请求
29 response = urllib.request.urlopen(request)
30 
31 # 8. 打印响应内容
32 print(response.read())

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-02-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Handler处理器 和 自定义Opener
  • 简单的自定义opener()
  • ProxyHandler处理器(代理设置)
  • HTTPPasswordMgrWithDefaultRealm()
  • ProxyBasicAuthHandler(代理授权验证)
相关产品与服务
多因子身份认证
多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档