urllib中包括了四个模块,包括:
模块名 | 备注 |
urllib.request | 可以用来发送request和获取request的结果 |
urllib.error | 包含了urllib.request产生的异常 |
urllib.parse | 用来解析和处理URL |
urllib.robotparse | 用来解析页面的robots.txt文件 |
使用urllib.request发送请求
(1)urllib.request.urlopen()基本使用
urllib.request 模块提供了最基本的构造 HTTP 请求的方法,利用它可以模拟浏览器的一个请求发起过程.
同时它还带有处理 authenticaton (授权验证), redirections (重定向), cookies (浏览器Cookies)以及其它内容。
通过输出结果可以发现它是一个 HTTPResposne 类型的对象
它主要包含的方法有:
read()
readinto()
getheader(name)
getheaders()
fileno()
主要包括的属性有:
msg
version
status
reason
debuglevel
closed等属性
得到这个对象之后,赋值为 response .
然后就可以用 response 调这些方法和属性,得到返回结果的一系列信息。
例如 response.read() 就可以得到返回的网页内容,
response.status 就可以得到返回结果的状态码,如200代表请求成功,404代表网页未找到等。
(2).request.urlopen()详解
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
除了第一个参数可以传递URL之外,我们还可以传递其它的内容,比如 data (附加参数), timeout (超时时间)等等。
data 参数是可选的,如果要添加 data ,它要是字节流编码格式的内容,即 bytes 类型,通过 bytes() 函数可以进行转化,另外如果你传递了这个 data 参数,它的请求方式就不再是 GET 方式请求,而是 POST 。
timeout 参数可以设置超时时间,单位为秒,意思就是如果请求超出了设置的这个时间还没有得到响应,就会抛出异常,如果不指定,就会使用全局默认时间。它支持 HTTP 、 HTTPS 、 FTP 请求。
常理来说,如果设置0.1秒内,name基本不可能得到服务器响应,因此输出了 TIME OUT 的提示。这样,我们可以通过设置 timeout 这个参数来实现超时处理,有时还是很有用的。
cafile和 capath 两个参数是指定 CA 证书和它的路径,这个在请求 HTTPS 链接时会有用。 context 参数,它必须是 ssl.SSLContext 类型,用来指定 SSL 设置。 cadefault 参数现在已经弃用了,默认为 False。
(3)urllib.request.Request的使用
我们知道利用 urlopen() 方法可以实现最基本请求的发起,但这几个简单的参数并不足以构建一个完整的请求,如果请求中需要加入 Headers 等信息,我们就可以利用更强大的 Request 类来 构建一个请求。 class urllib.request.Request(url,data = None,headers = {},origin_req_host = None,unverifiable = False,method = None ) 此类是URL请求的抽象。
第一个 url 参数是请求 URL,这个是必传参数,其他的都是可选参数。
第二个 data 参数如果要传必须传 bytes(字节流)类型的,如果是一个字典,可以先用 urllib.parse 模块里的 urlencode() 编码。
第三个 headers 参数是一个字典,这个就是 Request Headers 了,你可以在构造 Request 时通过 headers 参数直接构造,也可以通过调用 Request 实例的 add_header() 方法来添加, Request Headers 最常用的用法就是通过修改 User-Agent 来伪装浏览器,默认的 User-Agent 是 Python-urllib,我们可以通过修改它来伪装浏览器。
第四个 origin_req_host 参数指的是请求方的 host 名称或者 IP 地址。
第五个unverifiable 参数指的是这个请求是否是无法验证的,默认是False。意思就是说用户没有足够权限来选择接收这个请求的结果。例如我们请求一个 HTML 文档中的图片,但是我们没有自动抓取图像的权限,这时 unverifiable 的值就是 True。
第六个 method 参数是一个字符串,它用来指示请求使用的方法,比如GET,POST,PUT等等。
(4)urllib.request高级特性
介绍下 urllib.request.BaseHandler ,它是所有其他 Handler 的父类,它提供了最基本的 Handler 的方法,例如 default_open() 、 protocol_request() 等。
接下来就有各种 Handler 类继承这个 BaseHandler ,列举如下:
- HTTPDefaultErrorHandler 用于处理HTTP响应错误,错误都会抛出 * HTTPError 类型的异常。
- HTTPRedirectHandler 用于处理重定向。
- HTTPCookieProcessor 用于处理 Cookie 。
- ProxyHandler 用于设置代理,默认代理为空。
- HTTPPasswordMgr 用于管理密码,它维护了用户名密码的表。
- HTTPBasicAuthHandler 用于管理认证,如果一个链接打开时需要认证,那么可以用它来解决认证问题。 另外还有其他的 Handler ,可以参考官方文档。
异常处理
1.URLError:打开一个不存在的页面。
2.HTTPError:它有三个属性。
code,返回 HTTP Status Code,即状态码,比如 404 网页不存在,500 服务器内部错误等等。 reason,同父类一样,返回错误的原因。 headers,返回 Request Headers。
因为 URLError 是 HTTPError 的父类,所以我们可以先选择捕获子类的错误,再去捕获父类的错误 先捕获 HTTPError,获取它的错误状态码、原因、Headers 等详细信息。如果非 HTTPError,再捕获 URLError 异常,输出错误原因。最后用 else 来处理正常的逻辑,这是一个较好的异常处理写法。
解析链接
1:urlparse() 将传入的url解析成了六大部分,是一个元组,含协议名称、域名、路径等
result = urllib.parse.urlparse('http://www.baidu.com') urlparse ()方法将其拆分成了6 个部分 : ://前面的就是scheme ,代表协议; 第一个/符号前面便是netloc ,即域名, 后面是path ,即访问路径; 分号;前面是params ,代表参数; 问号?后面是查询条件query , 一般用作GET 类型的URL; 井号#后面是锚点,用于直接定位页面内部的下拉位置。
2:urlunparse() 将路径组合成url
data =['http','www.baidu.com','index.html','user','a=6','comment'] url = urllib.parse.urlunparse(data)
#必须有六个参数,没有为参数设置为空字符数
3:urlsplit() 这个方法和urlparse() 方法非常相似,只不过它不再单独解析params 这一部分,只运回5个结果。
4:urlunsplit() 它也是将链接各个部分组合成完整链接的方法,传人的参数也是一个可迭 代对象,例如列表、元组等,唯一的区别是长度必须为5 。
5:urljoin()
后面会覆盖前面,如果没有对应的,则会把前面的保留 该方法会分析base_url 的scheme 、netloc 和path这3 个内容并对新链接缺失的部分进行补充,最后返回结果。
url = urllib.parse.urljoin('http://www.baidu.com','https://baidu.com.index.html')
6:urlencode() 将字典编成请求的参数 需要post一些数据待处理时,通常用字典的形式封装起来交给urlencode处理
data={
'name':'qiushen',
'age':'25'
}
data = urllib.parse.urlencode(data)
url = 'http://www.baidu.com?'+ data
print(url)
#结果为:http://www.baidu.com?name=qiushen&age=2
7:parse_qs()
就可以将内容转回字典
qs = 'name=daqiushen&age=25'
print(urllib.parse.parse_qs(qs))
8:parse_qsl() 用于将参数转化为元组组成的列表
qs = 'name=daqiushen&age=25'
print(urllib.parse.parse_qsl(qs))
9:quote() 该方法可以将内容转化为URL 编码的格式。URL 中带有中文参数时,有时可能会导致乱码的问题,此时用这个方法可以将文字符转化为U RL 编码
keyword = '胡建秋'
url = 'https://www.baidu.com/s?wd=' +urllib.parse. quote(keyword)
分析Robots协议
1.Robots协议
Robots 协议也称作爬虫协议、机器人协议,它的全名叫作网络爬虫排除标准( Robots Exclusion Protocol ),用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取。它通常是一个叫作robots.txt的文本文件,一般放在网站的根目录下。当搜索爬虫访问一个站点时,它首先会检查这个站点根目录下是否存在robots.txt 文件,如果存在,搜索爬虫会根据其中定义的爬取范围来爬取。如果没有找到这个文件,搜索爬虫便会访问所有可直接访问的页面。
2.robot.txt
robots.txt必须放置在一个站点的根目录下,而且文件名必须全部小写
User-agent :定义搜索引擎类型 google蜘蛛:googlebot 百度蜘蛛:baiduspider yahoo蜘蛛:slurp alexa蜘蛛:iaarchiver msn蜘蛛:msnbot altavista蜘蛛:scooter lycos蜘蛛:lycos_spider(t-rex) alltheweb蜘蛛:fast-webcrawler
User-agent : * 代表所有的引擎种类,是一个通配符 Disallow: 禁止访问 Allow: 允许访问
3.robotparser(判断网页是否可以被抓取)
了解Robots 协议之后,我们就可以使用robot parser 模块来解析robots.txt 了。该模块提供了一个类RobotFileParser ,它可以根据某网站的robots.txt 文件来判断一个爬取爬虫是否有权限来爬取这个网页。该类用起来非常简单,只需要在构造方法里传人robots.txt 的链接即可。首先看一下它的声明:urllib.robotparser.RobotFileParser(url =’ ’) 当然,也可以在声明时不传人,默认为空,最后再使用set_url ()方法设置一下也可。 下面列刷了这个类常用的几个方法。
1:set_url(): 用来设置ro bots . txt 文件的链接。如果在创建RobotFileParser 对象时传入了链 接,那么就不需要再使用这个方法设置了。
2:read(): 读取robots .txt 文件并进行分析。注意,这个方法执行一个读取和分析操作,如果不调用这个方法, 接下来的判断都会为False ,所以一定记得调用这个方法。这个方法不会返回任何内容,但是执行了读取操作。
3:parse(): 用来解析robots.txt文件,传入的参数是robots . txt 某些行的内容,它会按照robots.txt的语法规则来分析这些内容。
4:can_fetch():该方法传人两个参数, 第一个是User-agent ,第二个是要抓取的URL 。返回的 内容是该搜索引擎是否可以抓取这个URL ,返回结果是True 或False
5:mtime(): 返回的是上次抓取和分析robots.txt 的时间,这对于长时间分析和抓取的搜索爬虫是 很有必要的,你可能需要定期检查来抓取最新的robots.txt 。
6:modified():它同样对长时间分析和抓取的搜索爬虫很有帮助,将当前时间设置为上次抓取和分析robots.txt 的时间。