Nodejs项目调用Scrapy爬虫

原来的思路是部署好反爬虫项目和scrapy爬虫后,通过nodejs网页项目调用scrapy实现爬虫并存储爬取数据,但是经过一番搜索,论坛上并没有之前的nodejs与scrapy交互的相应示例。因此尝试自己摸索nodejs的调用逻辑。

功能逻辑如下:网页客户端输入搜索关键词后单击爬取按钮调用服务器上爬虫程序,爬虫程序将爬取的到的数据保存成csv下载至服务器路径内。

在学习了node.js的官方文档后,发现child_process模块能够提供nodejs项目一个衍生子进程的功能。

child_process.exec(command[, options][, callback])

衍生 shell,然后在 shell 中执行 command,并缓冲任何产生的输出。 传给 exec 函数的 command 字符串会被shell 直接处理。

而scrapy爬虫的启动方式也可以通过shell命令:

scrapy crawl projectName -a args=XXX

因此通过该方法可以实现nodejs与shell建立管道传入command指令执行scrapy爬虫。

该方法的AP现总结如下:

  • child.stdin 获取标准输入
  • child.stdout 获取标准输出
  • child.stderr 获取标准错误输出
  • 获取子进程的PID:child.pid
  • 提供生成子进程的方法:child_process.spawn(cmd, args=[], [options])
  • 提供直接执行系统命令的方法:child_process.exec(cmd, [options], callback)
  • 提供调用脚本文件的方法:child_process.execFile(file, [args], [options], [callback])

接下来先编写前端界面与后端方法,实现前后端连通。前端界面包括一个input框以及一个提交button,实现逻辑为input框输入爬取关键词,button的click事件将keyword传至后台并拼接command命令通过管道调用scrapy。

index.ejs编写前端界面:

<div ng-controller="crawlerCtrl" id="crawlerPage" style="display: none;">
    <h1>数据爬取</h1>
  	<input type="text" id="keyword" name="keyword" placeholder="请输入数据关键词">
    <button ng-click="startCrawler()">提交爬虫</button>
</div>

前端提交http请求,调用后端函数调用爬虫,并通过后端响应判断是否调用成功。传入的参数为keyword,前端获取该参数并传至后端作为爬虫的参数:

var crawler = angular.module("crawler",[]);
        crawler.controller("crawlerCtrl", ["$scope", "$http",
        function ($scope, $http){
            $scope.startCrawler = function(){
                // 获取前端提交的keyword参数
                var keyword = document.getElementById("keyword").value;
                // alert(keyword);
                $http({
                        method: 'post',
                        url: '/crawler/startCrawler',
                        data: {
                            keyword : keyword
                        }
                    }).then(
                        function success(res) {
                            if (res.data.isSuccess === "1") {
                                alert("爬取成功!");
                            } else if (res.data.isSuccess === "0") {
                                alert("未成功调用");
                            } else if (res.data.isSuccess === "-1") {
                                alert("正在爬取...");
                            } else {
                                alert("路径下没有正确的爬虫项目");
                            }
                        }
                    );
            }

        }
    ]);

后端代码实现调用爬虫,编写crawler.js路由文件

// 使用child_process库实现建立与shell的管道通讯
var exec = require('child_process').exec;

后端回调函数:

第一次尝试我写的方法如下:

router.post('/startCrawler',function(req,res){

    var keyword = req.body.keyword;
    console.log(keyword);
    
    var cmdStr1 = 'cd /home/hjq/antiCrawler';
    exec(cmdStr1,function(err,stdout,stderr){
        if(err){
            res.send({'isSuccess':'-2'});
            return ;
        }
        else{
            var cmdStr2 = 'scrapy crawl antiCrawler -a keyword=' + keyword;
            console.log(cmdStr2);
            console.log(stdout);
            exec(cmdStr2,function(err,stdout,stderr){
                if(err){
                    console.log(err);
                    res.send({'isSuccess':'0'});
                    return ; 
                }
                else{
                    //爬虫正确执行
                    res.send({'isSuccess':'1'});
                    console.log(stdout);
                    return ;
                }
            });
        }
    });
    
    
});

即先建立第一次管道通信,切换工作路径至爬虫根路径下,再通过第二次管道通信执行爬虫。但是测试时报错:回传的是“0”号结果,意味着爬虫出现err,查看控制台返回的详细错误是:

Scrapy 1.8.0 - no active project

Unknown command: crawl

Use "scrapy" to see available commands

网上搜索给出的结论有两种:1. 不是爬虫的根目录;2. 缺失scrapy爬虫的cfg文件

因此大胆猜测是第一次管道通信结束后,切换的工作路径也同时丢失,导致第二次管道通信调用爬虫时是在nodejs的工作路径下调用的,自然就没法调用成功。

解决方法:

var cmdStr2 = 'cd /home/hjq/antiCrawler;scrapy crawl antiCrawler -a keyword=' + keyword;

将两条命令写成一条传入管道执行,成功调用。

爬虫保存数据成csv在项目pipelines中实现,此处不再赘述。

另外我还没测试通过管道通信shell连接ssh,若无法通过管道连接ssh那爬虫项目将要部署在客户端同一个服务器上,物理层要做出相应改变。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值