经验拾忆(纯手工)=> Scrapyd

发布时间:2019-09-28 08:37:44编辑:auto阅读(1718)

    前言

    我之前做的项目:一直用的 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()                             # 无关禁用的弹窗信息
              }
            }
          )
        },   
    },

    Docker+docker-compose

    如果你也想过使用docker+docker-compose (开启服务,推送代码一体化)
    请看下篇: https://segmentfault.com/a/11...

    结束语

    我是设置2个按钮(开启、关闭互斥,点哪个哪个就被禁用,与此同时另一个按钮就会被激活)。
    当然,你也可以用 单机,双击。等用一个按钮来控制开启和关闭。
    当然这些只是标志性的功能。 核心功能还是 Django视图中的 ScrapydAPI 这个API的使用
    python-scrapyd-api官档:https://pypi.org/project/pyth...

关键字