前两章讲网页的构成以及爬虫的基本原理,如果您还不了解,推荐您看上一章python网络爬虫教程(二):网页基础。学习了这些以后,就可以开始写代码了。
学习爬虫,最初的操作就是模拟浏览器向服务器发出请求,幸运的是,python为我们提供了强大且便捷的类库来完成这些请求,本章我们先来详细了解一下python自带的urllib库,他是python内置的HTTP请求库,不需要额外安装即可使用。在python2中,有urllib和urllib2两个库来实现请求的发送,而在python3中统一为了urllib,作者使用的是python3.7,也就是以python3的urllib来说明。
urllib包含了4个模块:
request:它是最基本的http请求模块,用来模拟发送请求。
error:异常处理模块,如果出现错误可以捕获这些异常。
parse:一个工具模块,提供了许多URL处理方法,如:拆分、解析、合并等。
robotparser:主要用来识别网站的robots.txt文件,然后判断哪些网站可以爬。
1. urllib.request(构造请求)
urllib.request模块提供了最基本的构造HTTP请求的方法,其中比较重要的类为urllib…request.urlopen,以python官网为例,我们来体验一下它的强大之处:
from urllib.request import urlopen
response = urlopen('https://www.python.org')
print(response.read().decode())
运行结果如下:上述代码中,我们用urlopen来构造HTTP请求,返回值是一个HTTPRsponse对象,用read()方法读取网页内容之后,返回的结果是网页字节流,用decode()解码成unicode之后即可得到网页源代码。除此之外,HTTPRsponse对象还拥有如下属性和方法:
import urllib.request import urlopen
response=urlopen('https://www.python.org') #请求站点获得一个HTTPResponse对象
print(response.read().decode('utf-8')) #返回网页内容
print(response.getheader('server')) #返回响应头中的server值
print(response.getheaders()) #以列表元祖对的形式返回响应头信息
print(response.fileno()) #返回文件描述符
print(response.version) #返回版本信息
print(response.status) #返回状态码200,404代表网页未找到
print(response.debuglevel) #返回调试等级
print(response.closed) #返回对象是否关闭布尔值
print(response.geturl()) #返回检索的URL
print(response.info()) #返回网页的头信息
print(response.getcode()) #返回响应的HTTP状态码
print(response.msg) #访问成功则返回ok
print(response.reason) #返回状态信息
urlopen参数信息如下:
urllib.request.urlopen(url,data=None,[timeout,],cafile=None,capath=None,cadefault=False,context=None)
data参数: 该参数是可选的,如果要添加该参数,需要将其内容编码为字节流格式即bytes类型,另外,如果传递了该参数,请求方式将使用POST请求:
from urllib.request import urlopen
import urllib.parse
dict= {
'Hello': 'Word!'}
data = bytes(urllib.parse.urlencode(dict), encoding='utf-8')
response = urlopen('http://httpbin.org/post', data=data)
print(response.read().decode())
data需要字节类型的参数,用urllib.parse的urlencode()可以将参数字典转换为字符串,然后再用bytes()函数将其转化为字节流。这里请求的站点是httpbin.org,它可以提供HTTP请求测试,它可以输出一些请求信息,运行结果如下:
{
"args": {},
"data": "",
"files": {},
"form": {
"Hello": "Word!"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "13",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Python-urllib/3.7",
"X-Amzn-Trace-Id": "Root=1-5ecb5d2d-8ee3f56e31828d78e4a10158"
},
"json": null,
"origin": "171.107.139.104",
"url": "http://httpbin.org/post"
}
可以看到传递的参数出现在了form字段中,这表明该请求以POST方式传输数据。
timeout参数:timeout参数用于设置超时时间,单位为秒,如果请求超出了设置时间还未得到响应则抛出异常:
from urllib.request import urlopen
response = urlopen('http://httpbin.org/post', timeout=0.1)
print(response.read().decode(