700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 【Python爬虫实战】用urllib与服务端交互(发送和接收数据)

【Python爬虫实战】用urllib与服务端交互(发送和接收数据)

时间:2021-05-31 09:34:36

相关推荐

【Python爬虫实战】用urllib与服务端交互(发送和接收数据)

本文节选自《Python爬虫技术:深入理解原理、技术与开发》。

urllib是Python3中内置的HTTP请求库,不需要单独安装,官方文档链接如下:

/3/library/urllib.html

从官方文档可以看出,urllib包含4个模块,如图1所示。

图1 urllib官方文档目录

这4个模块的功能描述如下:

request:最基本的HTTP请求模块,可以用来发送HTTP请求,并接收服务端的响应数据。这个过程就像在浏览器地址栏输入URL,然后按Enter键一样。

error:异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后根据实际情况,或者进行重试,或者直接忽略,或进行其他操作。

parse:工具模块,提供了很多处理URL的API,如拆分、解析、合并等。

robotparser:主要用来识别网站的robots.txt文件,然后判断哪些网站可以抓取,哪些网站不可以抓取。

本文主要介绍如何通过urllib发送HTTP GET请求和HTTP POST请求,并获取相应数据。

1. 用urlopen函数发送HTTP GET请求

urllib最基本的一个功能就是向服务端发送HTTP请求,然后接收服务端返回的响应数据。这个功能只需要通过urlopen函数就可以搞定。例如,下面的代码向百度发送HTTP GET请求,然后输出服务端的响应结果。

import urllib.requestresponse=urllib.request.urlopen('')# 将服务端的响应数据用utf-8解码print(response.read().decode('utf-8'))

运行结果如图2所示。

图2 百度首页的HTML代码

我们可以看到,使用urllib与服务端交互是非常容易的,除了import语句外,真正与业务有关的代码只有2行,就完成了整个与服务端交互的过程。其实这个过程已经完成了爬虫的第一步,就是从服务端获取HTML代码,然后就可以利用各种分析库对HTML代码进行解析,提取出我们感兴趣的URL、文本、图像等。

其实urlopen函数返回的是一个对象,而read是这个对象的一个方法,可以利用type方法输出这个对象的类型,当我们知道了对象类型后,就可以很容易知道这个对象中有哪些API,然后调用它们。

import urllib.requestresponse=urllib.request.urlopen('')print(type(response))

这段代码会输出如下的结果:

<class 'http.client.HTTPResponse'>

现在我们了解到,urlopen函数返回的是HTTPResponse类型的对象,主要包含read、getheader、getheaders等方法,以及msg、version、status、debuglevel、closed等属性。

下面是一个实际的案例,用来演示了HTTPResponse对象中主要的方法和属性的用法。

import urllib.request# 向京东商城发送HTTP GET请求,urlopen函数即可以使用http,也可以使用httpsresponse=urllib.request.urlopen('')# 输出urlopen函数返回值的数据类型print('response的类型:',type(response))# 输出响应状态码、响应消息和HTTP版本print('status:',response.status,' msg:',response.msg,' version:', response.version)# 输出所有的响应头信息print('headers:',response.getheaders())# 输出名为Content-Type的响应头信息print('headers.Content-Type',response.getheader('Content-Type'))# 输出京东商城首页所有的HTML代码(经过utf-8解码)print(response.read().decode('utf-8'))

运行结果如图3所示。

图3 HTTPResponse对象的API演示

2. 用urlopen函数发送HTTP POST请求

urlopen函数默认情况下发送的是HTTP GET请求,如果要发送HTTP POST请求,需要使用data命名参数,该参数是bytes类型,需要用bytes类将字符串形式的数据转换为bytes类型。

下面的例子向/post发送HTTP POST请求,并输出返回结果。

import urllib.request# 将表单数据转换为bytes类型,用utf-8编码data=bytes(urllib.parse.urlencode({'name':'Bill','age':30}),encoding='utf-8')# 提交HTTP POST请求response=urllib.request.urlopen('/post',data=data)# 输出响应数据print(response.read().decode('utf-8'))

这段代码中一开始提供了一个字典形式的表单数据,然后使用urlencode方法将字典类型的表单转换为字符串形式的表单,接下来将字符串形式的表单按utf-8编码转换为bytes类型,这就是要传给urlopen函数的data命名参数的值,要注意,一旦指定了data命名参数,urlopen函数就会向服务端提交HTTP POST请求,这里并不需要显式指定要提交的是POST请求。

本例将HTTP POST请求提交给了/post,这是一个用于测试HTTP POST请求的网址,如果请求成功,服务端会将HTTP POST请求信息原封不动地返回给客户端。

运行结果如图4所示。

图4 HTTP POST请求信息

- EOF -

推荐阅读点击标题可跳转

Python爬虫实战:抓取博客文章列表

卧槽,好强大的魔法,竟能让Python支持方法重载

Python装饰器(decorator)不过如此,是我想多了

这样合并Python字典,可以让程序的运行效率提高4倍

Python字典不是不可以排序,是你方法没用对!

文件侠告诉你,Python复制文件的N种姿势!

Python代码可以加密吗?Python字节码告诉你!

使出Python的六脉神剑,让Python拥有无限扩展性

看我用元类(metaclass)花式创建Python类

你不知道__name__变量是什么意思吗?

Python生成器(Generator)最完美解释

关注「极客起源」公众号,加星标,不错过精彩技术干货

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。