2.2 处理HTTP数据
HTTP是HyperText Transfer Protocol的缩写,含义是超文本传输协议。HTTP是互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。在本节的内容中,将详细讲解常用处理HTTP数据的知识。
2.2.1 使用内置的http包处理数据
在Python语言中,使用内置包http实现对HTTP协议的封装。在包http中主要包含如下所示的模块。
● http.client:底层的HTTP协议客户端,可以为urllib.request模块所用。
● http.server:提供处理socketserver模块的功能类。
● http.cookies:提供在HTTP传输过程中处理Cookies应用的功能类。
● http.cookiejar:提供实现Cookies持久化支持的功能类。
在http.client模块中,主要包括如下两个处理客户端应用的类。
● HTTPConnection:基于HTTP协议的访问客户端。
● HTTPResponse:基于HTTP协议的服务端回应。
在下面的实例文件fang.py中,演示了使用http.client.HTTPConnection对象访问指定网站的过程。
源码路径:daima\2\2-2\fang.py
在上述实例代码中只实现了一个基本的访问实例,首先,实例化http.client.HTTPConnection设置请求的方法为GET,然后,使用getresponse()方法获取访问的网页,并打印输出响应的状态。执行效果如图2-2所示。
在现实应用中,有时需要通过HTTP协议以客户端的形式访问多种服务,例如下载服务器中的数据,或与一个基于REST的API进行交互。通过使用urllib.request模块,可以实现简单的客户端访问任务,例如要发送一个简单的HTTP GET请求到远端服务器上,只需通过下面的实例文件fang1.py即可实现。
图2-2 执行效果
源码路径:daima\2\2-2\fang1.py
执行后会输出:
2.2.2 使用库requests处理数据
库Requests是用Python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,Requests会比urllib更加方便,可以节约开发者大量的时间。
可以使用如下两种命令安装库requests。
在下面的实例文件Requests01.py中,演示了使用库requests返回指定URL地址请求的过程。
源码路径:daima\2\2-2\Requests01.py
在上述代码中,创建了一个名为r的response对象,可以从这个对象中获取所有想要的信息。执行后会输出:
上述实例只演示get接口的用法,其他接口的用法也十分简单:
例如查询http://httpbin.org/get页面的具体参数,需要在url里面加上这个参数。假如查看有没有Host=httpbin.org这条数据,url形式应该是http://httpbin.org/get?Host=httpbin.org。在下面的实例文件Requests02.py中,提交的数据是往这个地址传送data里的数据。
源码路径:daima\2\2-2\Requests02.py
执行后会输出:
2.2.3 使用库httplib2处理数据
在Python程序中,经常使用第三方的开源库httplib2来处理HTTP数据。在使用库httplib2之前,需要使用如下两种命令安装库httplib2:
(1)获取内容
一旦拥有Http对象,能非常简单地获取网页数据,只需将要获取的数据的地址作为参数调用request()方法即可,这会对该url执行一个http GET请求。例如在下面的实例文件http201.py中,演示了使用库httplib2获取网页数据的过程。
源码路径:daima\2\2-2\http201.py
通过上述代码,方法request()会返回如下所示的两个值。
● 第一个:一个httplib2.Response对象,包含服务器返回的所有http头,如status为200则表示请求成功。
● 第二个:包含了HTTP服务器返回的实际数据的变量content。不是字符串的返回格式,而是以bytes对象数据的形式返回。如果需要返回一个字符串,需要确定字符编码,并自定义实现字符转换。
(2)处理缓存
与Python内置库http.client相比,库httplib2的最大优势是可以处理缓存数据。例如在下面的实例文件http202.py中,演示了使用库httplib2处理网页缓存数据的过程。
源码路径:daima\2\2-2\http202.py
执行后输出网页的源码,并获取带有缓存的HTTP对象h1,被存储在当前环境的“.cache"目录下。
在上述输出效果的最后一行中,显示debug值为True,说明是从本地的cache缓存进行读取的,没经过原网站运行解析,提高了输出速度。但如果不想读取缓存数据,则只需通过如下代码即可实现。
在使用库httplib2时,可以在发出的请求中添加任意的HTTP头部。为了跳过所有缓存,包括本地的磁盘缓存和远程服务器之间的缓存代理,只需在headers字典中加入上面的no-cache头即可。
(3)处理Last-Modified和ETag头
在HTTP协议中,定义了如下两个重要的属性。
● Last-Modified:标记此文件在服务器端的最后修改时间。
● Etag:用于标识URL对象是否改变。
根据上述两个属性,如果发现本地缓存已不是最新的,客户端可以在发送下一个请求时发送验证器来检查数据是否发生改变。如果数据没有改变,服务器会返回304状态码,但不返回数据。
(4)POST发送构造数据
在下面的实例文件http203.py中,演示了使用POST发送构造数据的过程。
源码路径:daima\2\2-2\http203.py
执行后会输出:
在上述代码中,add_credentials()方法的第三个参数identi.ca表示该证书的有效域名。建议读者一定要设置这个参数,如果省略了这个参数,当再次用httplib2.Http对象访问另一个需要认证的站点时,可能会导致httplib2将一个站点的用户名密码泄漏给其他站点,这样就会造成安全问题。
另外,因为httplib2返回的是字节串(bytes)数据,而不是字符串。所以为了将返回数据转化为字符串格式,需要用合适的字符编码进行解码。例如:
2.2.4 使用库urllib3处理数据
在Python应用中,库urllib3提供了一个线程安全的连接池,能够以post方式传输文件。可以使用如下两种命令安装库urllib3。
在下面的实例文件urllib303.py中,演示了使用库urllib3中的post()方法创建请求的过程。
源码路径:daima\2\2-2\urllib303.py
执行后会输出:
在下面的实例文件urllib305.py中,演示了使用库urllib3获取远程CSV数据的过程。
源码路径:daima\2\2-2\urllib305.py
执行后会将这两个远程CSV文件下载保存到本地,如图2-3所示。
图2-3 下载保存到本地的CSV文件
在下面的实例文件urllib302.py中,演示了使用库urllib3抓取显示凤凰网头条新闻的方法。
源码路径:daima\2\2-2\urllib302.py
由于头条新闻是随着时间的推移发生变化的,所以每次的执行效果可能不一样。