前言
我之前做的项目:一直用的 Linux 的 Screen 会话工具 + Scrapy 的 JOBDIR 来控制爬虫开关。
但是有后来想到用 Web 来控制爬虫的开关。所以我想到了用 Scrapyd 服务实现。
部署爬虫项目
安装 scrapyd 服务
pip install scrapyd
启动 scrapyd 服务
scrapyd # 就这一条 shell 命令即可启动服务
如果你相对爬虫服务做一些配置,(比如 log 目录,绑定地址,绑定端口。。等,可修改如下配置文件):
vi /usr/lib/python3.6/site-packages/scrapyd/default_scrapyd.conf
将爬虫程序推送到服务中
首先确保你的爬虫程序单测可以无误运行!
情况 1:(爬虫程序在 linux,上面讲的 scrapyd 服务也在 linux)
首先安装个模块:
pip install scrapyd-client
修改 scrapy 的 scrapy.cfg 文件:
[deploy:Cython_lin] # 这个 Cython_lin 是服务名,可自定义,但后面还会用到
url = http://23.23.xx.xx:6800/ # 这是你上面启动的 Scrapyd 服务的 URL+PORT
project = Baidu
# 这个文件是你运行 scrapy startproject 时 自动创建的文件。在项目根目录下,就叫 "scrapy.cfg":
正式推送本机爬虫程序到 Scrapyd:
如下有 3 个说明:1. 你需要在项目根目录下,执行这个命令
2. Cython_lin 就是我们上面 scrapy.cfg 文件 配置的服务名
3. Baidu 就是 scrapy.cfg 文件 里面的那个 project 属性的值,也是 项目名
scrapyd-deploy Cython_lin -p Baidu
情况 2,番外篇(Windows 开发,Linux 部署)
同样安装个客户端模块(windows):
pip install scrapyd-client
修改 scrapy 的 scrapy.cfg 文件 (windows):
[deploy:Cython_lin] # 这个 Cython_lin 是服务名,可自定义,但后面还会用到
url = http://23.23.xx.xx:6800/ # 这是你上面启动的 Scrapyd 服务的 URL+PORT
project = Baidu
建立一个文件名为 scrapyd-deploy.bat,内容作下(windows):
注意:这个文件是创建在 python 的安装路径下(如果你是虚拟环境,那么就去虚拟环境的 python 路径中)
@echo off
"D:\Virtualenv_All\scrapy\Scripts\python.exe" "D:\Virtualenv_All\scrapy\Scripts\scrapyd-deploy" %1 %2 %3 %4 %5 %6 %7 %8 %9
随后将刚才的路径,配置到环境变量中(如果不想设置环境变量,那么每次需要用绝对路径用 scrapyd-deploy)
scrapyd-deploy Cython_lin -p Baidu
这条命令和上面(linux 版本)讲的是一模一样的,同样要在 scrapy 根路径下执行
调用爬虫程序
前面我们已经完全将爬虫 Scrapyd 服务部署完成。接下来就是开启调用的环节:
scrapyd 采用 “ 请求接口 ” 的方式取开启或终止爬虫:
查看爬虫状况:
curl http://23.23.xx.xx:6800/daemonstatus.json
正式开启爬虫程序:
curl http://39.107.86.223:6800/schedule.json -d project=Baidu -d spider=zhidao
# 注意: "Baidu" 是项目名,而 "zhidao" 是每个 spider 的名字(就是主程序的爬虫名 name=...)# 注意: 开启的时候会给你一个 ID,你要记住它,方便我们停止
停止爬虫程序:
curl http://23.23.xx.xx:6800/cancel.json -d project=Baidu -d job= 运行 ID
Django 视图内嵌控制爬虫程序
上面我们说了用 curl 发送请求去操控爬虫的开启与暂停。但是这并不是习惯的做法。
更好的是,通过 Qt 或者 通过 Web, 来操控爬虫。
pip install python-scrapyd-api # 预先安装此模块
from scrapyd_api import ScrapydAPI
scrapyd = ScrapydAPI('39.107.xx.xx:6800') # 先获取 scrapyd 远程服务的客户端连接
class SpiderView(View): # 我使用的是 Django 的 CBV
def get(self, request):
state_dict = scrapyd.list_jobs('Baidu') # 列出项目所有爬虫任务,返回字典
if request.GET.get('tag') == 'start': # 检测爬虫是否为运行状态
scrapyd.schedule('Baidu', 'zhidao') # 'project_name', 'spider_name'
return HttpResponse('0') # 如果正在运行,给前端一个值,按钮
if request.GET.get('tag') == 'stop': # 前端点下按钮如果 get 传值为 stop
try:
state = state_dict['running'][0]['id'] # 若取不到,就抛异常
except:
return HttpResponse('-1') # 随便返回一个值,不用处理
scrapyd.cancel('Baidu', state) # 根据 id 取消 爬虫入伍
return HttpResponse('0') # 并返回 0(这个 0 是我自定义的,前端也用的 0)return HttpResponse('')
前端交接
其实后端接口做好了,前端就随意了。我用的 Nuxt+Vue,主要贴一下核心 method 吧:
methods: {start() {
axios.get('http://39.xx.xx:8000/spider', { # 注意这时请求的 Django
params: {'tag': 'start'}
}).then((response) => {this.tag = Number.parseInt(response['data'])
if (this.tag === 0) { # 如果 django 返回值为 0
this.start_msg = '开启成功,切记不要重复开启' # 用于 vue 模板提示
this.start_unable = true # 把按钮禁用,防止重复请求
this.stop_unable = false # 同时把停止按钮由禁用设置为激活
this.start_layer() # 这个函数内部实现了消息弹框
// this.stop_unable = false
}
}
),
stop() {
axios.get('http://39.107.xx.xx:8000/spider', { # 注意这是请求的 Django
params: {'tag': 'stop'} # 发一个 stop 参数的 get 请求
}).then((response) => {this.tag = Number.parseInt(response['data'])
if (this.tag === 0) { # 如果返回 0, 这个 0 是我在 Django 自己指定的。this.stop_msg = '关闭成功,切记不要重复关闭'
this.start_unable= false # 负负得正,开始按钮激活
this.stop_unable = true # 停止按钮禁用
this.stop_layer() # 无关禁用的弹窗信息}
}
)
},
},
结束语 + 注意
我是设置 2 个按钮(开启、关闭互斥,点哪个哪个就被禁用,与此同时另一个按钮就会被激活)。
当然,你也可以用 单机,双击。等用一个按钮来控制开启和关闭。
当然这些只是标志性的功能。核心功能还是 Django 视图中的 ScrapydAPI 这个 API 的使用
python-scrapyd-api 官档:https://pypi.org/project/pyth…