python爬虫学习笔记-urllib的使用

学习爬虫,最基本的操作即为模拟浏览器向服务器发出请求,python内置了一个名为urllib的内置HTTP请求库,有了它,我们只需要关心请求的链接是什么,需要传递什么参数,以及设置请求头等其他信息即可。这样,我们就不用深入底层的连接具体是怎样传输和通信(当然,这是站在巨人的肩膀上)。urllib库包含4个模块:
request:urllib的请求模块,模拟发送请求;
error:异常处理模块,用于在请求错误时捕获异常;
parse:提供了URL的一些处理方法,包括拆分,解析,合并等;
robotparser:用于识别网站的robot.txt文件,用于判断网站是否可爬;
1.爬虫的第一步即为向服务器发送请求,request模块提供了皆不能的构造HTTP请求的方法-urlopen()。下面以抓取百度首页为例:

import urllib.request
res=urllib.request.urlopen('https://www.baidu.com')
print(res.read().decode('utf-8'))

运行结果如下:

<html>

<head>

	<script>

		location.replace(location.href.replace("https://","http://"));

	</script>

</head>

<body>

	<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>

</body>

</html>

我们看到得到的是html代码,但是我们爬取的目的是得到想要的信息,首先看一下返回的到底是什么,利用type()方法:

print(type(res))#返回结果:<class 'http.client.HTTPResponse'>

可以发现这是一个HTTPResponse类型的对象它包含read(),getheaders()等方法,接下来可以得到返回值的其他信息:

print(res.status)
print(res.getheaders())
print(res.getheader('Server'))

返回结果:

200
[('Accept-Ranges', 'bytes'), ('Cache-Control', 'no-cache'), ('Content-Length', '227'), ('Content-Type', 'text/html'), ('Date', 'Sat, 17 Nov 2018 02:06:19 GMT'), ('Etag', '"5becd3d4-e3"'), ('Last-Modified', 'Thu, 15 Nov 2018 02:03:00 GMT'), ('P3p', 'CP=" OTI DSP COR IVA OUR IND COM "'), ('Pragma', 'no-cache'), ('Server', 'BWS/1.1'), ('Set-Cookie', 'BD_NOT_HTTPS=1; path=/; Max-Age=300'), ('Set-Cookie', 'BIDUPSID=9176DB820AEC79EC1B99BDD045E9C693; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com'), ('Set-Cookie', 'PSTM=1542420379; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com'), ('Strict-Transport-Security', 'max-age=0'), ('X-Ua-Compatible', 'IE=Edge,chrome=1'), ('Connection', 'close')]
BWS/1.1

这里分别获得信息为响应的状态码(200代表响应成功),响应的头信息以及服务器类型。

2.request方法除url参数外还可传递data,timeout,context,cafile,capath参数,下面一一说明:
data参数:使用浏览器查看网页检查元素(f12),找到network下的headers信息,发现有“Request Method: GET”,这是说明网页的请求方法,这种方法我们只需要传递url参数就可以获得源码,但有些网页信息的请求需要向服务器发送一个字典参数作为请求参数,此时的Request Method会变成Post,urllib中要传递这个参数需要使用bytes()方法将字典参数转换为字节流编码格式,即bytes类型,实例如下:

import urllib.parse
import urllib.request
data=bytes(urllib.parse.urlencode({'word','hello'}),encoding='utf-8')
res=urllib.request.urlopen('http:httpbin.org/post',data=data)
print(res.read())

3.timeout参数:
用于设置超时时间,单位为s,指如果请求超出了设置的这个时间还没有获得响应,就抛出异常,如果不指定,则默认全局时间,实例如下:

import urllib.request
import urllib.error
import socket
try:
    res=urllib.request.urlopen('http:httpbin.org/get',timeout=0.01)
except urllib.error.URLError as e:	
    print('Time Out')

0.01s不可能得到响应,所以输出结果TimeOut。
3.其他参数:
context:指定设置SSL;
cafile,capath分别指定CA证书和路径。
4.构造Request对象请求:
urlopen()方法的参数之前是url,在这里也可以将Request对象作为独立的参数导入,可以方便的配置Request参数.代码如下:

res=urllib.request.Request('https://www.baidu.com')
rep=urllib.request.urlopen(res)
print(rep.read().decode('utf-8'))

Request参数包括url,data,headers(此参数用来伪装浏览器,为字典参数,chrome为User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36),host名称等;
5.高级用法
Handler:前面的方法可以构造请求,但涉及到例如cookies处理,代理设置等高级操作就需要使用Handler,我们可以把它理解为某种处理器,有专门处理登陆,有的处理cookies,有设置代理的。
urllib.request模块里的BaseHandler类是所有Handler类的父类,我们使用继承BaseHandler父类的Handler子类来完成我们所需要的操作,举例如下:

HTTPDefaultErrorHandler:用于处理HTTP响应错误,抛出HTTPError异常;
HTTPRedirectHandler:用于处理重新定向;
HTTPCookieProcessor:用于处理cookies;
ProxyHandler:用于设置代理;
与之相关的还有一个称作Opener的东西,OPener可以使用open(),作用和urlopen相同,我们可以使用Hnadler构建Opener;
实例如下:

扫描二维码关注公众号,回复: 4114122 查看本文章
from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLError
usename='usename'
password='password'
url='http:localhost:5000/'
p=HTTPPasswordMgrWithDefaultRealm()
#添加用户名,密码
p.add_password(None,url,usename,password)#建立一个处理验证的Handler
#构建opener
auth_handler=HTTPBasicAuthHandler(p)
opener=build_opener(auth_handler)

如果请求的页面需要输入用户名和密码应该如何处理呢?这里利用HTTPPasswordMgrWithDefaultRealm的实例化对象的add——password()方法传递用户名和密码,这样就建立了一个处理验证的Handler,接下来再使用build_opener()方法构建Opener,使用Opener来发送请求,最后使用OPener的open()方法打开链接就完成验证;
代理:
添加代理,首先引入ProxyHandler,它的参数为字典类型,键名为协议类型,键值为代理连接,可添加多个代理,实例代码如下:

proxy_handlers=ProxyHandler({'https':'https://127.0.0.1:9743'})#可添加多个代理
opener1=build_opener(proxy_handlers)
try:
	result=opener.open('https://www.baidu.com')
	print(result.read().decode('utf-8'))
except URLError as e:
	print(e.reason)

利用build——opener方法构建一个Opener,最后使用open()方法发送请求即可。
6.链接的解析
urlparse-URL的识别与分段,实例如下:

from urllib.parse import urlparse
result=urlparse('https://baidu.com/index.html;user?id=5#comment')
print(type(result), result)

输出结果为:<class ‘urllib.parse.ParseResult’>
ParseResult(scheme=‘https’, netloc=‘baidu.com’, path=’/index.html’, params=‘user’, query=‘id=5’, fragment=‘comment’)#返回结果将url拆分成6部分
与之对立的方法为urlunparse,实现URL的构造它接受的参数是一个可迭代对象,但长度必须为6。

7.分析Robots协议
Robots协议叫做爬虫协议,用来告诉爬虫和搜索引擎页面是否可以抓取,它通常是一个叫做robots.txt的文本文件,存储再网站的根目录下。
举例如下:
User-agent:*
Disallow:/
Allow:/public/
这是一个robots.txt文件的内容,它实现了只允许爬取public目录的功能。

以上就是对urllib的简单总结,当然,鼓励学会了使用requests库之后也没有人会用这个了,不过了解python内置的库使用还是有价值的。

猜你喜欢

转载自blog.csdn.net/weixin_42672765/article/details/84177121