使用urllib
简介
- 在python2中,有urllib和urllib2两个库。在python3中,统一为urllib。
- 他是python内置的http请求库,无需额外安装即可使用。
- 包含如下四个模块
- request:最基本的HTTP请求模块,用来模拟发送请求,只需要传入url以及额外的参数。
- error:异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作以保证程序不会意外终止。
- parse:一个工具模块,提供了许多URL处理方法。
- robotparser:用来识别网站的robots.txt文件,判断网站是否可以爬。
发送请求
- urlopen()
urllib.request模块提供了最基本的构造http请求的方法,利用他可以模拟浏览器的请求发起过程,同时他还带有授权验证、重定向、浏览西cookies以及其他内容。
以百度为例:
1 2 3 4
| import urllib.request
response = urllib.request.urlopen('https://baidu.com') print(response.read().decode('utf-8'))
|
运行上述代码,就会完成对百度首页的抓取,输出网页的源代码。
接下来,利用type()方法输出相应的类型:
1 2 3 4
| import urllib.request
response = urllib.request.urlopen('https://baidu.com') print(type(response))
|
运行上述代码输出结果如下:
1 2
| [python@localhost python3webspider]$ python3 urlopen.py <class 'http.client.HTTPResponse'>
|
可以发现,他是一个HTTPResposne类型的对象,得到这个对象后,我们把他赋值为response变量,然后就可以调用相应的方法属性得到结果的一系列信息。
例如,调用read()方法可以得到返回的网页内容,调用status属性可以得到返回结果的状态码。示例如下:
1 2 3 4 5 6
| import urllib.request response = urllib.request.urlopen('https://baidu.com') print(response.status) print(response.getheaders()) print(response.getheader('Server'))
|
运行上述代码输出结果如下:
1 2 3 4
| [python@localhost python3webspider]$ python3 urlopen.py 200 [('Bdpagetype', '1'), ('Bdqid', '0xd4cb8f3e000412de'), ('Cache-Control', 'private'), ('Content-Type', 'text/html'), ('Cxy_all', 'baidu+4762ec06d8ecda4e5726dd1f0275df33'), ('Date', 'Sun, 25 Nov 2018 05:58:11 GMT'), ('Expires', 'Sun, 25 Nov 2018 05:58:07 GMT'), ('P3p', 'CP=" OTI DSP COR IVA OUR IND COM "'), ('Server', 'BWS/1.1'), ('Set-Cookie', 'BAIDUID=3B091DC52784E6AE2AE89A9DD6B9370D:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com'), ('Set-Cookie', 'BIDUPSID=3B091DC52784E6AE2AE89A9DD6B9370D; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com'), ('Set-Cookie', 'PSTM=1543125491; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com'), ('Set-Cookie', 'delPer=0; path=/; domain=.baidu.com'), ('Set-Cookie', 'BDSVRTM=0; path=/'), ('Set-Cookie', 'BD_HOME=0; path=/'), ('Set-Cookie', 'H_PS_PSSID=1466_21078_26350_20718; path=/; domain=.baidu.com'), ('Vary', 'Accept-Encoding'), ('X-Ua-Compatible', 'IE=Edge,chrome=1'), ('Connection', 'close'), ('Transfer-Encoding', 'chunked')] BWS/1.1
|
传递参数
利用最基本的urlopen()方法可以完成get请求,但是有时需要给连接传递一些参数。
urlopen()函数API如下:
1
| urllib.request.urlopen(url,data=None.[timeout,]*,cafile=None,capath=None,cadefaule=Flase,contest=None)
|
可以发现,除了第一个参数可以传递url之外,还可以传递data,timeout等参数。下面介绍这几个参数的用法:
data参数是可选的,如果要增加该参数,需要使用bytes()方法将参数转换为字节流编码格式内容,即bytes类型。另外,如果传递了这个参数,那请求类型就不再是GET,而是POST。
示例如下:
1 2 3 4 5 6
| import urllib.parse import urllib.request data = bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8') response = urllib.request.urlopen('http://httpbin.org/post',data=data) print(response.read())
|
运行示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| [python@localhost python3webspider]$ python3 urlopen_data.py b'{\n "args": {}, \n "data": "", \n "files": {}, \n "form": {\n "word": "hello"\n }, \n "headers": {\n "Accept-Encoding": "identity", \n "Connection": "close", \n "Content-Length": "10", \n "Content-Type": "application/x-www-form-urlencoded", \n "Host": "httpbin.org", \n "User-Agent": "Python-urllib/3.6"\n }, \n "json": null, \n "origin": "222.91.125.114", \n "url": "http://httpbin.org/post"\n}\n' [python@localhost python3webspider]$ python3 urlopen_data.py | sed 's/\\n/\n/g' b'{ "args": {}, "data": "", "files": {}, "form": { "word": "hello" }, "headers": { "Accept-Encoding": "identity", "Connection": "close", "Content-Length": "10", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "Python-urllib/3.6" }, "json": null, "origin": "222.91.125.114", "url": "http://httpbin.org/post" } '
|
这里我们传递了一个参数word,值是hello。他需要被转码成bytes类型。采用了bytes方法,该方法的第一个参数需要是str类型,需要用urllib.parse模块里的urlencode()方法将参数字典转化为字符串;第二个参数指定编码格式,这里指定为utf8.
请求的站点为httpbin.org,他提供HTTP请求测试。本地请求的url为http://httobin.org/post,这个链接可以用来测试post请求,他可以输出请求的信息,其中包括data参数。
我们传递的参数出现在了form字段中,说明模拟了表单提交的方式传递了数据。