更强大的工具Handler登场 ,可以理解为各种处理器,有专门处理登陆验证的,有处理cookies的,有处理代理设置的。利用它们,我们几乎可以做到HTTP请求中的所有事。
首先介绍的BaseHandler类,它是所有Handler的父类,它提供了最基本的方法,例如default_open()、protocol_request()等
接下来,就有各种Handler子类继承这个BaseHandler类,举例如下:
HTTPDefaultErrorHandler:用于处理HTTP响应错误,错误都会抛出HTTPError类型的异常。
HTTPRedirectHandler:用于处理重定向(什么是重定向)
HTTPCookieProcessor:用于处理Cookies
ProxyHandler:用于设置代理,默认代理为空
HTTPPasswordMgr:用于管理密码,它维护 了用户名和密码的表
HTTPBasicAuthHandler:用于管理认证,如果一个链接打开时
from urllib import request,error
username='username'
password='password'
url='http://localhost:5000/'
创建密码管理对象,用来保存需要处理的用户名和密码
p=request.HTTPPasswordMgrWithDefaultRealm()
添加账户信息,第一个参数realm是与远程服务器相关的域信息,一般没人管它都是写None,后面三个参数分别是 代理服务器、用户名、密码
p.add_password(None,url,username,password)
auth_handler=request.HTTPBasicAuthHandler(p)
opener=request.build_opener(auth_handler)
try:
response=opener.open(url)
html=response.read().decode('utf-8')
print(html)
except error.URLError as e:
print(e.reason)#错误原因
这里首先实例化了HTTPBasicAuthHandler对象,其参数是HTTPPasswordMgrWithDefaultRealm对象,它利用add_password()添加进去用户名和密码,这样就建立了一个处理验证的Handler。
接下来,利用这个Handler并使用build_open()方法构建一个Opener,这个Opener在发送请求时就相当于验证成功了。
接下来,利用Opener的open()方法打开链接,就可以完成验证了。这里获取到的结果就是验证后面的页面源码内容。
在做代理的时候免不了要使用代理,如果要添加代理,可以这样做:
from urllib.error import URLError
from urllib.request import ProxyHandler,build_opener
proxy_handler = ProxyHandler({
'http':'http://127.0.0.1:9743'
'https':'http://127.0.0.1:9743'
})
opener = build_opener(proxy_handler)
try:
response = opener.open('http://www.baidu.com')
print(response.read().decode('utf-8')
except URLError as e:
print(e.reason)
这里我们本地搭建了一个代理,它运行在9743端口上。
这里使用了ProxyHandler,其参数是一个字典,键名是协议类型。简直是代理链接,可以添加多个代理。
import http.cookiejar,urllib.request
cookie = http.cookiejar.CookieJar()
handler =urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
for item in cookie:
print(item.name+"="+item.value)
解析链接
parse模块,定义了处理URL的标准接口,例如如何实现URL各种部分的抽取合并以及链接转换 。支持的链接类型涉及大部分协议。
1.urlparse() 该方法实现了URL的识别和分段(useer-->user),对url链接默认分段
from urllib.parse import urlparse
result = urlparse('http://www.baidu.con/index.html;useer?id=5#comment')
print(result)
print(result.netloc)
结果:
2.urlunparse()将链接段拼接成一个链接
from urllib.parse import urlunparse
data = ['http','www.baidu.com','index.htm','user','a=6','comment']
print(urlunparse(data))这里data用了列表类型,当然可以选用其他类型,比如元组或者特定的数据结构。
打印结果为:http://www.baidu.com/index.htm;user?a=6#comment
3.urlsplit()
这个方法与urlparse()方法非常相似,只不过它不再单独解析params这一部分,只返回5个结果params会合并入path中。
4.urlunsplit()
这个方法与urlunparse()方法非常相似,将链接连接起来。将分段或者两个链接拼接在一起!
5.urljoin()
同urllib.request.urljoin()同作用。
6.urlencode()
解析编码
7.parse_qs()
有了序列化就一定会反序列化。如果我们有一串GET请求参数,利用parse_qs()方法,就可以转化回字典。
from urllib.parse import parse_qs
query='name=germey&age=22'
print(parse_qs(query))
运行结果:
{'name':['germey'],'age':['22']}
8.parse_qsl()
这个方法可以用于将参数转换成元组组成的列表
from urllib.parse import parse_qsl
query='name=germey&age=22'
print(parse_qsl(query))
运行结果:
[('name','germey'),('age','22')]
9.quote() 该方法可以将内容转化为URL编码格式。URL中带有中文参数时,有时可能会导致乱码的问题,此时用这个方法可以将中文字符转化为URL编码。
from urllib.parse import quote
keyword = '壁纸'
url = 'https://wwww.baidu.com/s?wd'+quote(keyword) )
print(url)
10.unquote() 该方法用于解码。与quote相反
利用urllib的robotparser模块,我们可以实现网站Robots协议的分析。
1.Robots协议
Robots协议也称作爬虫协议机器人协议,它的全名叫做网络爬虫排除标准,用来告诉爬虫和搜索引擎哪些页面可以抓取。它通常是一个robots.txt文件
当搜索爬虫访问一个站点时,它首先会检查这个站点根目录下是否存在robots.txt文件,如果存在搜索爬虫会根据其定义的爬取范围来爬取。如果没有找到这个文件,搜索爬虫便会访问所有可直接访问的页面。
User-agent:*
Disallow:/
Allow:/public/
User-agent 描述了爬虫的名称,设置为*表示都可以
Disallow指定了不允许抓取的目录,这里不允许抓取所有的
Allow 一般和Disallow一起使用,用来排除某些限制,这样我们表示所有的页面都不可以抓取。但是可以抓取public目录。
2.爬虫名称
搜索引擎里面基本上都是有一个爬虫名称
3.rbobotparser
了解Robots协议后,就可以使用robotsparser模块来解析robots.txt 。该模块还提供了一个类RobotFileParse,它可以根据某网站的robots.txt文件来判断一个爬虫爬取是否有权限来爬取这个网页。
用起来非常简单,只需要在构造方法中传入robots.txt的链接即可。urllib.robotparse.RobotFileParse(url=' ')
几个常用方法:
set-url():用来设置robots.txt文件的链接;
read()读取robots.txt文件并进行分析。这个方法不hi返回任何内容,但是执行了读取操作。
parse()用来解析robots.txt文件,传入的参数是robots.txt某些行的内容
can_fetch() 该方法传入两个参数,第一个是User-agent 第二个是要抓取的URL 返回的是该搜索引擎是否可以抓取。
mtime():返回的是上次抓取和分析robots.txt的时间,这对于长时间分析和抓取的搜索爬虫是很有必要的,你可能需要定期检查来抓取最新的robots.txt
modified() 它同样对长时间分析和抓取的搜索爬虫有帮助,将当前时间设置为上次抓取和分析robots.txt的时间
from urllib.robotparser import RobotFileParser
rp = RobotFileParser()
rp.set_url('http://www.jianshu.com/robots.txt')
rp.read()
print(rp.can_fetch('*','http://jianshu,com/p/b67554025d7d'))