Scrapyrt实战指南 - 将爬虫转换为HTTP API服务
📂 所属阶段:第五阶段 — 战力升级(分布式与进阶篇)
🔗 相关章节:Scrapy-Redis分布式架构 · Docker容器化爬虫
你有没有遇到过这种情况:写好了一个完美的 Scrapy 爬虫,却不知道怎么快速丢给后端、前端甚至第三方调用?或者想做一个“输入一个 URL → 返回结构化数据”的实时接口,又不想从零搭建 Flask / django 服务?今天这篇指南,带你用 3 分钟把爬虫变成 HTTP API,轻松搞定所有烦恼!
🎯 Scrapyrt 是什么?
Scrapyrt(Scrapy Real-Time)是 Scrapy 官方维护的轻量级插件。它的魔力在于:你不需要修改任何爬虫代码,就能直接把整个 Scrapy 项目变成一个 RESTful API 服务。
它特别适合下面这些场景:
- 用户触发的“即时按需爬取”(比如用户输入商品链接,实时抓取价格)
- 微服务架构里的“数据采集组件”(通过 HTTP 调用,与其它服务解耦)
- API 网关后方的“安全数据接口”(只需暴露一个经过认证的端点)
总结一下,Scrapyrt 有四大核心优势:
- 服务化架构:爬虫直接变成可调用的 Web 服务
- 无状态、易扩展:每个请求独立,易于横向扩展
- JSON 格式通信:前后端都喜欢的交互方式
- 与现有 Scrapy 项目完美兼容:不需要改动原来的
settings.py、middleware 等
🚀 3 分钟快速启动
第一步:准备环境与项目
确保你的 Python 版本 ≥ 3.6,然后安装 Scrapy 和 Scrapyrt:
pip install scrapy scrapyrt
接着快速创建一个示例 Scrapy 项目,并生成一个基础爬虫:
scrapy startproject demo_spider
cd demo_spider
scrapy genspider example example.com
此时你的目录结构大概是这样:
demo_spider/
├── demo_spider/
│ ├── spiders/
│ │ └── example.py
│ └── settings.py
└── scrapy.cfg
第二步:改造一行代码,让爬虫支持动态 URL
打开 demo_spider/spiders/example.py,把 start_requests 方法改成下面这样(其余保持不变):
import scrapy
class ExampleSpider(scrapy.Spider):
name = 'example'
# 核心修改:通过 API 传递的 url 参数动态生成请求
def start_requests(self):
# 从属性中获取传入的 url(可以是字符串或列表)
urls = getattr(self, 'url', None)
if urls:
# 统一处理成列表形式,兼容单个 URL 和多个 URL
urls = [urls] if isinstance(urls, str) else urls
for url in urls:
yield scrapy.Request(url, callback=self.parse)
def parse(self, response):
yield {
'url': response.url,
'title': response.css('title::text').get().strip(),
'status': response.status
}
要点解释:
- 我们用
getattr(self, 'url', None) 获取调用方传过来的 url 参数。
- 如果传的是字符串,就变成列表;如果已经是列表,则直接遍历。
- 这样就允许一次请求传入多个 URL,非常灵活。
第三步:启动服务
在 demo_spider 根目录下(就是能看到 scrapy.cfg 的位置),执行:
默认会监听 0.0.0.0:6023。控制台会输出类似 Starting Scrapyrt 1.2.0 on http://0.0.0.0:6023 的信息,表示服务启动成功。
第四步:验证服务
打开浏览器或终端,输入:
curl "http://localhost:6023/crawl.json?spider_name=example&url=https://httpbin.org/get"
你会立刻收到一个 JSON 响应,其中的 items 字段就包含了爬虫解析出来的数据(网页标题、状态码等)。就这么简单,一个实时爬虫 API 就跑起来了!
🔌 核心 API 详解
Scrapyrt 主要提供了两个核心端点,可以覆盖绝大多数使用场景。
1. /crawl.json —— 同步爬取(最常用)
请求方式:GET
适用场景:小数据量、短时间的爬取任务(比如单个页面、轻量级列表)
示例:
curl "http://localhost:6023/crawl.json?spider_name=example&url=https://httpbin.org/get&max_requests=3"
如果想传多个 URL,可以在 url 参数中传入 & 分隔的多个值(实际行为取决于你的爬虫如何处理 url 列表),但更推荐使用 crawl_args 传递 JSON 列表:
curl "http://localhost:6023/crawl.json?spider_name=example&crawl_args=%7B%22url%22%3A%5B%22https://httpbin.org/get%22%2C%22https://httpbin.org/headers%22%5D%7D"
(其中 %7B%22url%22%3A%5B... 是 {"url":["...","..."]} 的 URL 编码,你也可以用 Python 或 Postman 直接构造)
2. /crawl.json/request —— 自定义 Request(POST)
请求方式:POST
适用场景:需要自定义 Headers、Cookies、Request Meta 等的复杂请求
请求体示例:
curl -X POST http://localhost:6023/crawl.json/request \
-H "Content-Type: application/json" \
-d '{
"spider_name": "example",
"request": {
"url": "https://httpbin.org/headers",
"headers": {
"User-Agent": "Custom Spider 1.0"
},
"meta": {
"custom_key": "custom_value"
}
}
}'
这种方式让你几乎完全控制 Scrapy 的 Request 对象,包括 cookies、method 等,非常灵活。
🐍 Python 极简客户端
如果你不想每次都手写 curl,可以封装一个几行代码的 Python 客户端,方便在其它项目中调用:
import requests
class ScrapyrtClient:
def __init__(self, base_url="http://localhost:6023"):
self.base_url = base_url.rstrip('/')
def crawl(self, spider_name, url, **kwargs):
params = {"spider_name": spider_name, "url": url}
params.update(kwargs) # 支持 max_requests、crawl_args 等
resp = requests.get(f"{self.base_url}/crawl.json", params=params, timeout=300)
resp.raise_for_status()
return resp.json()
# 使用示例
client = ScrapyrtClient()
result = client.crawl("example", "https://httpbin.org/get")
print(result['items'][0]['title'])
同时,你也可以基于这个客户端封装异步调用、错误重试等逻辑,很适合集成到你的后端服务里。
🔒 快速安全加固(生产必备)
直接裸奔上生产?绝对不行!这里给出三个最实用的安全措施。
1. Nginx 反向代理 + HTTPS
让 Scrapyrt 只监听内网地址,前面放一个 Nginx 处理 HTTPS、认证和限流。
简单配置示例(/etc/nginx/conf.d/scrapyrt.conf):
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
location / {
# 只允许信任的 IP 访问(比如公司办公网、API 网关)
allow 123.45.67.89;
deny all;
proxy_pass http://127.0.0.1:6023;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
2. 添加简单的 API Key 验证
可以通过 Nginx 的 auth_request 模块配合一个认证服务来做,或者在 Scrapyrt 前加一个简单的 Flask 代理,验证 Authorization 头。这里不展开完整实现,但是思路一定要有。
3. 限流防滥用
在 Nginx 里加上速率限制,避免单一客户端疯狂调用:
limit_req_zone $binary_remote_addr zone=scrapyrt:10m rate=5r/s;
server {
...
location / {
limit_req zone=scrapyrt burst=10 nodelay;
proxy_pass http://127.0.0.1:6023;
}
}
有了这三板斧,你的 API 服务就安全多了。
🐳 Docker 一键部署
容器化部署可以让环境一致,也方便横向扩展。我准备了一个简单的 Dockerfile,你可以直接使用:
FROM python:3.9-slim
WORKDIR /app
# 安装编译依赖(有些 lxml 等库需要)
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc libxml2-dev libxslt1-dev && \
rm -rf /var/lib/apt/lists/*
# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 安装 Scrapyrt
RUN pip install scrapyrt
# 复制整个项目
COPY . .
EXPOSE 6023
# 健康检查:每 30 秒访问一次根路径
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
CMD curl -f http://localhost:6023/ || exit 1
CMD ["scrapyrt", "-p", "6023", "-i", "/app"]
其中 requirements.txt 里包含 Scrapy 等依赖,例如:
然后构建并运行:
docker build -t scrapyrt-demo .
docker run -d -p 6023:6023 --name scrapyrt-container scrapyrt-demo
现在你就可以在宿主机上通过 http://localhost:6023 访问到容器内的爬虫服务了。如果想在 Compose 中与其他服务联动,也只需要几行配置。
❌ 高频问题排查
在实际使用中,你可能会遇到这几个坑,别慌,解决方案都在这里。
1. 端口被占用
# 查看谁占用了端口
lsof -i :6023
# 或者换一个端口启动
scrapyrt -p 6024
2. 爬虫超时
有些网站响应慢,或者爬虫逻辑较复杂,默认超时时间可能不够。可以通过启动参数和 Scrapy 设置共同调整:
# 启动时增加整体任务超时(秒)
scrapyrt -p 6023 --timeout 600
同时,在项目的 settings.py 中增加下载超时:
DOWNLOAD_TIMEOUT = 120 # 单个请求最多等 120 秒
3. 返回数据太大
如果爬虫抓取了太多页面,可能会撑爆内存或响应时间过长。可以在 API 参数里限制总请求数:
curl "http://localhost:6023/crawl.json?spider_name=example&url=xxx&max_requests=5"
或者在 Scrapy 设置里限制并发和深度:
CONCURRENT_REQUESTS = 8
DEPTH_LIMIT = 2
💡 核心最佳实践
最后,送你五条“压箱底”的建议,帮你把 Scrapyrt 用得又稳又好:
- 容器化部署:用 Docker 隔离环境,方便一键部署和快速扩容。
- Nginx 反向代理:统一加 HTTPS、IP 白名单、速率限制,把安全做在前头。
- 限制资源:每个 API 调用最好都设置
max_requests,同时在 Scrapyrt 启动时通过 --max-concurrent-requests 控制全局并发。
- 日志管理:如果你用 Docker,可使用
json-file 或 syslog 驱动;如果是裸机部署,记得配置 logrotate,别让日志撑爆磁盘。
- 健康检查:在 Dockerfile 或 Compose 中加上健康检查,配合编排工具自动重启异常服务,提升可用性。
🏷️ 标签云:Scrapyrt HTTP API 实时爬虫 微服务 按需爬取 Docker部署