# 13.11 Scrapyrt 的使用

Scrapyrt 为 Scrapy 提供了一个调度的 HTTP 接口。有了它我们不需要再执行 Scrapy 命令，而是通过请求一个 HTTP 接口即可调度 Scrapy 任务，我们就不需要借助于命令行来启动项目了。如果项目是在远程服务器运行，利用它来启动项目是个不错的选择。

### 1. 本节目标

我们以本章 Scrapy 入门项目为例来说明 Scrapyrt 的使用方法，项目源代码地址为：[https://github.com/Python3WebSpider/ScrapyTutorial](https://github.com/Python3WebSpider/ScrapyTutorial)。

### 2. 准备工作

请确保 Scrapyrt 已经正确安装并正常运行，具体安装可以参考第 1 章的说明。

### 3. 启动服务

首先将项目下载下来，在项目目录下运行 Scrapyrt，假设当前服务运行在 9080 端口上。下面将简单介绍 Scrapyrt 的使用方法。

### 4. GET 请求

目前，GET 请求方式支持如下的参数。
* spider_name，Spider 名称，字符串类型，必传参数，如果传递的 Spider 名称不存在则会返回 404 错误。
* url，爬取链接，字符串类型，如果起始链接没有定义的话就必须要传递，如果传递了该参数，Scrapy 会直接用该 URL 生成 Request，而直接忽略 start_requests() 方法和 start_urls 属性的定义。
* callback，回调函数名称，字符串类型，可选参数，如果传递了就会使用此回调函数处理，否则会默认使用 Spider 内定义的回调函数。
* max_requests，最大请求数量，数值类型，可选参数，它定义了 Scrapy 执行请求的 Request 的最大限制，如定义为 5，则最多只执行 5 次 Request 请求，其余的则会被忽略。
* start_requests，是否要执行 start_request() 函数，布尔类型，可选参数，在 Scrapy 项目中如果定义了 start_requests() 方法，那么在项目启动时会默认调用该方法，但是在 Scrapyrt 就不一样了，它默认不执行 start_requests() 方法，如果要执行，需要将它设置为 true。

例如我们执行如下命令：

```
curl http://localhost:9080/crawl.json?spider_name=quotes&url=http://quotes.toscrape.com/
```

得到类似如下结果，如图 13-28 所示：

![](./assets/13-28.jpg)

图 13-28 输出结果

返回的是一个 JSON 格式的字符串，我们解析它的结构，如下所示：

```json
{
  "status": "ok",
  "items": [
    {
      "text": "“The world as we have created it is a process of o...",
      "author": "Albert Einstein",
      "tags": [
        "change",
        "deep-thoughts",
        "thinking",
        "world"
      ]
    },
    ...
    {
      "text": "“... a mind needs books as a sword needs a whetsto...",
      "author": "George R.R. Martin",
      "tags": [
        "books",
        "mind"
      ]
    }
  ],
  "items_dropped": [],
  "stats": {
    "downloader/request_bytes": 2892,
    "downloader/request_count": 11,
    "downloader/request_method_count/GET": 11,
    "downloader/response_bytes": 24812,
    "downloader/response_count": 11,
    "downloader/response_status_count/200": 10,
    "downloader/response_status_count/404": 1,
    "dupefilter/filtered": 1,
    "finish_reason": "finished",
    "finish_time": "2017-07-12 15:09:02",
    "item_scraped_count": 100,
    "log_count/DEBUG": 112,
    "log_count/INFO": 8,
    "memusage/max": 52510720,
    "memusage/startup": 52510720,
    "request_depth_max": 10,
    "response_received_count": 11,
    "scheduler/dequeued": 10,
    "scheduler/dequeued/memory": 10,
    "scheduler/enqueued": 10,
    "scheduler/enqueued/memory": 10,
    "start_time": "2017-07-12 15:08:56"
  },
  "spider_name": "quotes"
}
```

这里省略了 items 绝大部分。status 显示了爬取的状态，items 部分是 Scrapy 项目的爬取结果，items_dropped 是被忽略的 Item 列表，stats 是爬取结果的统计情况。此结果和直接运行 Scrapy 项目得到的统计是相同的。

这样一来，我们就通过 HTTP 接口调度 Scrapy 项目并获取爬取结果，如果 Scrapy 项目部署在服务器上，我们可以通过开启一个 Scrapyrt 服务实现任务的调度并直接取到爬取结果，这很方便。

### 5. POST 请求

除了 GET 请求，我们还可以通过 POST 请求来请求 Scrapyrt。但是此处 Request Body 必须是一个合法的 JSON 配置，在 JSON 里面可以配置相应的参数，支持的配置参数更多。

目前，JSON 配置支持如下参数。

* **spider_name**：Spider 名称，字符串类型，必传参数。如果传递的 Spider 名称不存在，则返回 404 错误。

* **max_requests**：最大请求数量，数值类型，可选参数。它定义了 Scrapy 执行请求的 Request 的最大限制，如定义为 5，则表示最多只执行 5 次 Request 请求，其余的则会被忽略。

* **request**：Request 配置，JSON 对象，必传参数。通过该参数可以定义 Request 的各个参数，必须指定 url 字段来指定爬取链接，其他字段可选。

我们看一个 JSON 配置实例，如下所示：

```json
{
    "request": {
        "url": "http://quotes.toscrape.com/",
        "callback": "parse",
        "dont_filter": "True",
        "cookies": {"foo": "bar"}
    },
    "max_requests": 2,
    "spider_name": "quotes"
}
```
我们执行如下命令传递该 Json 配置并发起 POST 请求：
```
curl http://localhost:9080/crawl.json -d '{"request": {"url": "http://quotes.toscrape.com/", "dont_filter": "True", "callback": "parse", "cookies": {"foo": "bar"}}, "max_requests": 2, "spider_name": "quotes"}'
```

运行结果和上文类似，同样是输出了爬取状态、结果、统计信息等内容。

### 6. 结语

以上内容便是 Scrapyrt 的相关用法介绍。通过它，我们方便地调度 Scrapy 项目的运行并获取爬取结果。更多的使用方法可以参考官方文档：http://scrapyrt.readthedocs.io。