使用相关的 Handler处理器
来创建特定功能的处理器对象;
然后通过 urllib.request.build_opener()
方法使用这些处理器对象,创建自定义opener对象;
使用自定义的opener对象,调用open()
方法发送请求。
urllib.resquest.install_opener()
将自定义的 opener 对象 定义为 全局opener,表示如果之后凡是调用urlopen,都将使用这个opener(根据自己的需求来选择)
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 打开,这样程序在执行的时候,会把收包和发包的报头在屏幕上自动打印出来,方便调试,有时可以省去抓包的工作。
使用代理IP,这是爬虫/反爬虫的第二大招,通常也是最好用的。
很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正常人,它会禁止这个IP的访问。
所以我们可以设置一些代理服务器,每隔一段时间换一个代理,就算IP被禁止,依然可以换个IP继续爬取。
urllib.request中通过ProxyHandler来设置使用代理服务器,下面代码说明如何使用自定义opener来使用代理:
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()
类将创建一个密码管理对象,用来保存 HTTP 请求相关的用户名和密码,主要应用两个场景:
ProxyBasicAuthHandler()
)
HTTPBasicAuthHandler()
)
如果我们使用之前的代码来使用私密代理,会报 HTTP 407 错误,表示代理没有通过身份验证:
urllib2.HTTPError: HTTP Error 407: Proxy Authentication Required
所以我们需要改写代码,通过:
HTTPPasswordMgrWithDefaultRealm()
:来保存私密代理的用户密码
ProxyBasicAuthHandler()
:来处理代理的身份验证。
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())