快速开始
基于Ruia快速实现一个以Hacker News为目标的爬虫 本文主要通过对hacker News的爬取示例来展示如何使用ruia。
第一步:定义item
item的目的是定义目标网站你需要爬取的数据,此时,爬虫的目标数据就是页面中的title和url,怎么提取数据,ruia的field类提供了以下三种方式提取目标数据
- xpath
- re
- css selector
本教程爬虫例子都默认使用css selector的规则来提取目标数据
规则确定后,就可以用 item来实现一个针对目标数据的 orm,创建文件 items.py
|
|
这段代码含义是:针对我们提取的目标html,我们定义了一个HackerNewsItem类,其包含了两个field
- title:直接从文本提取
- url:从属性提取
而 target_item是什么。对于一个 Item类来说,当其定义好网页目标数据后,ruia提供两种方式进行获取 Item
- get_item:获取网页的单目标,比如目标网页的标题,此时无需定义target_item
- get_items:获取网页的多目标,比如当前目标网页Hacker News中的title和url一共有30个,这时就必须定义target_item来寻找多个目标块;target_item的作用就是针对这样的工作而诞生的,开发者只要定义好这个属性(此时Ruia会自动获取网页中30个target_item),然后每个target_item里面包含的title和url就会被提取出来
第二步:测试Item
Ruia为了方便扩展以及自由地组合使用,本身各个模块之间耦合度是极低的,每个模块都可以在你的项目中单独使用;你甚至只使用ruia.Item、Ruia.TextField和ruia.AttrField来编写一个简单的爬虫
第三步:编写Spider
Ruia.Spider是Ruia框架里面的核心控制类
- 控制目标网页的请求 Ruia.Request和 Ruia.Response
- 可加载自定义钩子,插件以及相关配置等,让开发效率更高
开发者实现 HackerNewsSpider 必须是 Spider的子类,代码出现的两个方法 Spider内置:
- parse:此方法是Spider的入口,每一个start_urls的响应必然会被parse方法捕捉并执行;
- process_item:此方法作用是抽离出对Item提取结果的处理过程,比如这里会接受自定义Item类作为输入,然后进行处理持久化到文件。
第四步:运行Start
如果你想在异步函数里面调用,执行**await HackerNewsSpider.start()**即可
第五步:扩展
Middleware的目的是对每次请求前后进行一番处理 Ruia已经专门编写了一个名为 ruia-ua的插件来为开发者提升效率。示例代码
|
|
MongoDB
数据持久化,如果想将数据持久化到数据库(MongoDB)中,该怎么做?此时就到了凸显Ruia插件优势的时候了,你只需要安装 ruia-motor
|
|
入门指南
概览
Ruia是一个基于 asyncio和 aiohttp的异步爬虫框架,理念:
- 更少的代码:能通用的功能就插件化,让开发者直接引用即可
- 更快的速度:由异步驱动
安装
定义Item
运行 Spider
基础概念
Request
Request的主要作用是方便处理网络请求,最终返回一个 Request对象
主要提供的方法有
- Request().fetch:请求一个网页资源,可以单独使用
- Request().fetch_callback:为 Spider类提供的核心方法
核心参数
- url:请求的资源连接
- method:请求的方法
- callback:回调函数
- headers:请求头
- load_js:目标网页是否需要加载js
- metadata:跨请求传递的一些数据
- request_config:请求配置
- request_session: aiohttp的请求 session
- aiohttp-kwargs:请求目标资源可定义的其他参数
Request通过对 aiohttp和 pyppeteer的封装来实现对网页资源的异步请求
Response
Respoonse的目的是返回一个统一切友好的响应对象
- url:请求的资源连接
- metadata:跨请求传递的一些数据
- html:源网站返回的资源数据
- cookies:网站cookie
- history:访问历史
- headers:请求头
- status:请求状态码
Item
Item的主要作用是定义以及通过一定的规则提取网页中的目标数据,它主要提供了
- get_item:针对页面单目标数据进行提取
- get_items:针对页面多目标数据进行提取
Core arguments
- html:网页源码
- url:网页连接
- html_etree:etree._Element对象
不论是源网站链接或者网站HTML源码,甚至是经过lxml处理过的etree._Element对象,Item能接收这三种类型的输入并进行处理
有时你会遇见这样一种情况,例如爬取Github的Issue时,你会发现一个Issue可能对应多个Tag。 这时,将Tag作为一个独立的Item来提取是不划算的, 我们可以使用Field字段的many=True参数,使这个字段返回一个列表。
最终 Item类会将输入最终转化为etree._Element对象进行处理,然后利用元类的思想将每一个 Field构造的属性计算为原网页上对应的真实数据
Selector
Selector通过Field类实现,为开发者提供了CSS Selector和XPath两种方式提取目标数据,具体由下面两个类实现:
- AttrField(BaseField):提取网页标签的属性数据
- TextField(BaseField):提取网页标签的text属性
核心参数
所有 Field共有的参数
- default:str;设置默认值,建议定义,否则找不到字段时会报错
- many:bool,返回值将是一个列表
AttrField TextField HtmlField共有参数
- css_select:str,利用 CSS Select提取目标数据
- xpath_select:str,利用 XPath提取目标数据
AttrField需要一个额外的参数
- attr:目标标签属性
RegexField需要一个额外的参数
- re_select:str,正则表达式字符串
定好CSS Selector或XPath规则,然后利用lxml实现对目标html进行目标数据的提取
Spider
Spider是爬虫程序的入口,它将Item,Middleware,Request,等模块组合在一起,从而为你构造一个稳健的爬虫程序。你只需要关注以下两个函数:
- Spider.start:爬虫的启动函数
- parse:爬虫的第一层解析函数,继承 Spider的子类必须实现这个函数
核心参数:
Spider.start的参数
- after_start:爬虫启动后的钩子函数
- before_stop:爬虫启动前的钩子函数
- middleware:中间件类,可以是一个中间件 **Middleware()**实例,也可以是一组 **Middleware()**实例组成的列表
- loop:事件循环
Spider会自动读取start_urls列表里面的请求链接,然后维护一个异步队列,使用生产消费者模式进行爬取,爬虫程序一直循环直到没有调用函数为止
Middleware
Middleware的主要作用是在进行一个请求的前后进行一些处理,比如监听请求或者响应:
- Middleware().request:在请求前处理一些事情
- Middleware().response:在请求后处理一些事情
使用中间件有两点需要注意,一个是处理函数需要带上特定的参数,第二个是不需要返回值,具体使用如下:
|
|
Middleware通过装饰器来实现对函数的回调,从而让开发者可以优雅的实现中间件功能,Middleware类中的两个属性request_middleware和response_middleware分别维护着一个队列来处理开发者定义的处理函数