urllib
版本:在Python2中,有urllib和urllib2两个库来实现请求的发送。而在python3中,已经不存在urllib2这个库了,统一为urllib。
简介:urllib是python内置的http请求库,也就是说不需要额外安装即可使用。它包含如下四个模块。
request:它是最基本的 HTTP 请求模块,可以用来模拟发送请求。就像在浏览器里输入网址然后回车一样,只需要给库方法传入URL及额外的参数,就可以模拟实现这个过程了
parse :一个工具模块,提供了许多 URL 处理方法,比如拆分、解析、合并等
error :常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作以保证程序不会意外终止
robotparser :主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬,它其实用得比较少
1、请求模块:urllib.request
urllib.request.urlopen()
urlopen()方法中的url参数可以是字符串,也可以是一个Request对象
作用 :向网站发起一个请求并获取响应
字节流 = response.read()
字符串 = response.read().decode(“utf-8”)
# url可以是字符串
import urllib.request
resp = urllib.request.urlopen('https://www.baidu.com')
print(resp.read().decode('utf-8')) # read()获取响应对象的内容,内容是bytes字节流,需要转换成字符串
接下来,我们可以看看它返回的是什么,通过type()方法输出响应的类型:
import urllib.request
resp = urllib.request.urlopen('https://www.baidu.com')
print(type(resp))
>>> <class 'http.client.HTTPResponse'>
# 可以发现,它是一个HTTPResponse类型的对象,包含一些方法及属性
# 得到这个对象后,我们可以调用这些方法和属性,得到相应的一系列信息
例如,通过调用read()方法可以得到返回的网页内容,调用status属性或getcode()方法可以得到返回的状态码,调用geturl() 返回实际数据的URL(防止重定向问题)。
# 下面再通过一个实例来看看:
import urllib.request
resp = urllib.request.urlopen('http://www.baidu.com')
print(resp.status) # 获取响应的状态码 和 getcode()作用相同
print(resp.getheaders()) # 获取响应头相关信息(元组列表)
print(resp.getheader('Server')) # 获取具体的名称对应的值,"Server"大小写不区分
运行结果如下:
可见,前两个输出分别输出了响应状态码和响应的头信息,最后一个输出通过调用getheader()方法并传递一个参数,获得了响应头中的Server值,表示服务器是用Nginx搭建的。
如果想给链接传递一些参数,该怎样实现呢?
首先看一下urllib()函数的API:
urllib.request.urlopen(url,data=None,timeout=socket._GLOBAL_DEFAULT_TIMEOUT,*,cafile=None,capath=None, cadefault=False, context=None)
可以发现,除了第一个参数可以传递URL之外,我们还可以传递其他内容,比如data(附加数据)、timeout(超时时间)等。
data参数:POST请求
data参数是可选的,如果要添加这个参数,则需要以bytes类型提交,可以通过bytes()方法转化,不能是str类型
也可以在Request方法中添加data参数 urllib.request.Request(url,data=data)
import urllib.request, urllib.parse
data = bytes(urllib.parse.urlencode('字典'), encoding='utf-8') # 将字符串类型数据转换为bytes类型,该方法的第一个参数需要是str类型,第二个参数指定编码格式
resp = urllib.request.urlopen(url, data=data)
print(resp.read())
timeout参数:设置请求超时时间
该参数用于设置超时时间,单位为秒,意思就是如果请求超出了设置的这个时间,还没有得到请求,就会抛出异常。如果不指定参数,就会使用全局默认时间。
#设置请求超时时间
import urllib.request
resp = urllib.request.urlopen('https://www.baidu.com', timeout=0.1)
print(resp.read().decode('utf-8'))
>>> urllib.error.URLError: <urlopen error timed out>
这里我们设置的超时时间是0.1秒。程序在0.1秒过后,服务器依然没有响应,于是抛出URLError异常。该异常属于urllib