python爬虫008
基本库的使用
学习爬虫、最初的操作便是模拟浏览器向服务器发出请求,那么我们需要从哪个地方做起呢?请求需要我们自己来构造吗?需要关心请求这个数据结构的实现吗?需要了解 HTTP、TCP、IP 层的网络传输通信吗?需要知道服务器的响应和应答原理吗?
可能你无从下手,不过不用担心,Python 的强大之处就是提供了功能齐全的类库来帮助我们完成这些请求。最基础的HTTP库有urllib、httplib2、requests、treq等。
拿 urlib 这个库来说,有了它,我们只需要关心请求的链接是什么,需要传的参数是什么,以及如何设置可选的请求头就好了,不用深人到底层去了解它到底是怎样传输和通信的。有了它,两行代码就可以完成一个请求和响应的处理过程,得到网页内容,是不是感觉方便极了?
接下来,就让我们从最基础的部分开始了解这些库的使用方法吧。
使用urlib
在Python2中,有urllib和urllib2两个库来实现请求的发送。而在 Python3中已经不存在urllib2这个库了,统一为urllib,其官方文档链接为: https://docspython.org/3/library/urllib.html。
首先,了解一下urllib库,它是 Python 内置的 HTTP请求库,也就是说不需要额外安装即可使用它包含如下4个模块。
- request: 它是最基本的HTTP 请求模块,可以用来模拟发送请求。就像在浏览器里输人网址然后回车一样,只需要给库方法传入URL以及额外的参数,就可以模拟实现这个过程了。
- erro: 异常处理模块,如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作以保证程序不会意外终止。
- parse:一个工具模块,提供了许多URL处理方法,比如拆分、解析、合并等。
- robotparser:主要是用来识别网站的robotstxt文件,然后判断哪些网站可以爬,哪些网站不可以爬,它其实用得比较少。
这里重点讲解一下前3个模块。
发送请求
使用 urllib 的 request 模块,我们可以方便地实现请求的发送并得到响应。本节就来看下它的具体用法。
1.urlopen()
ullib.request 模块提供了最基本的构造 HTTP请求的方法,利用它可以模拟测览器的一个请求发起过程,同时它还带有处理授权验证(autenicarion )重定向(redirection)、浏览器 Cookies 以及其他内容。
下面我们来看一下它的强大之处。这里以 ython官网为例,我们来把这个网页抓下来:
import urllib.request
response = urllib.request.urlopen('https://www.python.org‘)
print(response.read().decode('utf-8'))
这里我们只用了两行代码,便完成了 Python 官网的抓取,输出了网页的源代码。得到源代码之后呢?我们想要的链接、图片地址、文本信息不就都可以提取出来了吗?
接下来,看看它返回的到底是什么。利用 type()方法输出响应的类型:
import urllib.request
response = urllib.request.urlopen('https://www.python.org')
print(type(response))
输出结果如下:
<class"http.client.HTTPResponse">
可以发现,它是一个HTTPResposne类型的对象,主要包含 read()、readinto()、getheader(name)getheaders()、fileno()等方法,以及 msg、version、 status、reason、 debuglevel、 closed等属性。
得到这个对象之后,我们把它赋值为 response 变量,然后就可以调用这些方法和属性,得到返回结果的一系列信息了。
例如,调用 read()方法可以得到返回的网页内容,调用 status 属性可以得到返回结果的状态码。
如200代表请求成功,404代表网页未找到等。
下面再通过一个实例来看看:
import urllib.request
response = urllib.request.urlopen(https://www.python.org')
print(response.status)
print(response.getheaders())
print(response.getheader('server'))
运行结果如下:
[('Server',"nginx"),('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-0ptions ",'SAMEORIGIN'),('x-Clacks-0verhead','GN Terry Pratchett'),('Content-Length','47397),('Accept-Ranges',bytes')200("Date',"Mon, 01 Aug 2016 09:57:31 GMT'), ('Via'"1.1 varnish'), ('Age',"2473'), ('Connection", 'close')x-served-By',"cache-lcy1125-LCY'),('X-Cache','HIT'),('X-Cache-Hits','23'),("ary","Cookie')('Strict-Transport-Security’,'max-age=63072000; includeSubDomains')]
可见,前两个输出分别输出了响应的状态码和响应的头信息,最后一个输出通过调用getheader()方法并传递一个参数 Server获取了响应头中的 Server 值,结果是 nginx,意思是服务器是用 Nginx搭建的。
利用最基本的urlopen()方法,可以完成最基本的简单网页的GET请求抓取。
如果想给链接传递一些参数,该怎么实现呢?首先看一下urlopen()函数的API:
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
可以发现,除了第一个参数可以传递 URL 之外,我们还可以传递其他内容,比如 data (附加数据)timeout(超时时间)等。
下面我们详细说明下这几个参数的用法。
data参数
data 参数是可选的。如果要添加该参数,需要使用 bytes()方法将参数转化为字节流编码格式的内容,即bytes类型。另外,如果传递了这个参数,则它的请求方式就不再是 GET方式,而是POST方式。
下面用实例来看一下:
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())
这里我们传递了一个参数 word,值是 hello。它需要被转码成 bytes(字节流)类型。其中转字节流采用了 bytes()方法,该方法的第一个参数需要是 str(字符串)类型,需要用 urllib.parse 块里的urlencode()方法来将参数字典转化为字符串;第二个参数指定编码格式,这里指定为 utf8。
这里请求的站点是 htpbin.org,它可以提供 HTTP 请求测试。本次我们请求的 URL 为 htp:/htpbinorpost,这个链接可以用来测试 POST请求,它可以输出请求的一些信息,其中包含我们传递的 data参数。
我们传递的参数出现在了form字段中,这表明是模拟了表单提交的方式,以POST方式传输数据。
timeout参数
timeout 参数用于设置超时时间,单位为秒,意思就是如果请求超出了设置的这个时间,还没有得到响应,就会抛出异常。如果不指定该参数,就会使用全局默认时间。它支持 HTTP、HTTPS、FTP请求。
- 点赞
- 收藏
- 关注作者
评论(0)