找回密码

如何实现一个Python爬虫框架

什么是爬虫框架

说这个之前,得先说说什么是框架

是实现业界标准的组件规范:比如众所周知的MVC开发规范

提供规范所要求之基础功能的软件产品:比如Django框架就是MVC的开发框架,但它还提供了其他基础功能帮助我们快速开发,比如中间件、认证系统等

爬虫流程:

请求&响应

解析

持久化

这三个流程有没有可能以一种优雅的形式串联起来,Ruia目前是这样实现的,请看代码示例:

可以看到,Item & Field类结合一起实现了字段的解析提取,Spider类结合Request * Response类实现了对爬虫程序整体的控制,从而可以如同流水线一般编写爬虫,最后返回的item可以根据使用者自身的需求进行持久化,这几行代码,我们就实现了获取目标网页请求、字段解析提取、持久化这三个流程

实现了基本流程规范之后,我们继而就可以考虑一些基础功能,让使用者编写爬虫可以更加轻松,比如:中间件(Ruia里面的Middleware)、提供一些hook让用户编写爬虫更方便(比如ruia-motor)

这些想明白之后,接下来就可以愉快地编写自己心目中的爬虫框架了

首先,我对Ruia爬虫框架的定位很清楚,基于asyncio & aiohttp的一个轻量的、异步爬虫框架,怎么实现呢,我觉得以下几点需要遵守:

轻量级,专注于抓取、解析和良好的API接口

插件化,各个模块耦合程度尽量低,目的是容易编写自定义插件

速度,异步无阻塞框架,需要对速度有一定追求

什么是爬虫框架如今我们已经很清楚了,现在急需要做的就是将流程规范利用Python语言实现出来,怎么实现,分为哪几个模块,可以看如下图示:

同时让我们结合上面一节的Ruia代码来从业务逻辑角度看看这几个模块到底是什么意思:

Request:请求

Response:响应

Item & Field:解析提取

Spider:爬虫程序的控制中心,将请求、响应、解析、存储结合起来

这四个部分我们可以简单地使用五个类来实现,在开始讲解之前,请先克隆Ruia框架到本地:

然后用PyCharm打开Ruia项目:

选择刚刚pipenv配置好的python解释器:

此时可以完整地看到项目代码:

好,环境以及源码准备完毕,接下来将结合代码讲述一个爬虫框架的编写流程

Request & Response

Request类的目的是对aiohttp加一层封装进行模拟请求,功能如下:

封装GET、POST两种请求方式

增加回调机制

自定义重试次数、休眠时间、超时、重试解决方案、请求是否成功验证等功能

将返回的一系列数据封装成Response类返回

接下来就简单了,不过就是实现上述需求,首先,需要实现一个函数来抓取目标url,比如命名为fetch:

实际运行一下,会输出请求状态200,就这样简单封装一下,我们已经有了自己的请求类Request,接下来只需要再完善一下重试机制以及将返回的属性封装一下就基本完成了:

最终代码见ruia/request.py即可,接下来就可以利用Request来实际请求一个目标网页,如下:

这段代码请求了目标网页https://docs.python-ruia.org/并返回了Response对象,其中Response提供属性介绍如下:

Field & Item

实现了对目标网页的请求,接下来就是对目标网页进行字段提取,我觉得ORM的思想很适合用在这里,我们只需要定义一个Item类,类里面每个属性都可以用Field类来定义,然后只需要传入url或者html,执行过后Item类里面 定义的属性会自动被提取出来变成目标字段值

可能说起来比较拗口,下面直接演示一下可能你就明白这样写的好,假设你的需求是获取HackerNews网页的title和url,可以这样实现:

从输出结果可以看到,title和url属性已经被赋与实际的目标值,这样写起来是不是很简洁清晰也很明了呢?

来看看怎么实现,Field类的目的是提供多种方式让开发者提取网页字段,比如:

XPath

CSS Selector

RE

所以我们只需要根据需求,定义父类然后再利用不同的提取方式实现子类即可,代码如下:

核心类就是上面的代码,具体实现请看ruia/field.py

接下来继续说Item部分,这部分实际上是对ORM那块的实现,用到的知识点是元类,因为我们需要控制类的创建行为:

相关推荐