如何组合两个都需要监听端口的Express模块​​?

时间:2015-10-13 23:25:25

标签: node.js express cheerio

我正在尝试创建一个Web scraper,用户在表单中输入一个URL,当他们点击提交时,刮刀获取URL,然后返回有关我指定的URL的数据。

我的主要app.js文件是:

// Dependencies
var express = require('express');
var path = require('path');
var fs = require('fs');

// Custom Libraries - ./ signals to node not to look in the node_modules directory
var scraper = require('./scraper');

// App.js Variables
var app = express();
var viewsPath = path.join(__dirname, '/app/views');
app.use(express.static(__dirname + '/app/public'));

// set the port - 3000
app.set('port', process.env.PORT || 3000);

// Form handling
app.use(require('body-parser').urlencoded({
extended:true }));
app.get('/the_test');
// Writes the domain entered in the form to app/data/domain.txt
app.post('/process', function(request, response){
    var domain = request.body.domain;

    fs.writeFile('app/data/domain.txt', domain, function (err) {
      if (err) return console.log(err);
      console.log('Your domain has been saved!');;
    });

    response.redirect(303, '/results');
});

// Routes require
var routes = require('./routes');
app.use('/', routes);
app.use('/results', routes);

app.listen(app.get('port'), function(){
    console.log('Express started on http://localhost:' + app.get('port') + '; press Ctrl-C to terminate.');
});

我的刮刀文件是:

var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');

var scraper = express();
// Scrape the url that was posted
scraper.get('/scrape', function(req, res){
  // Scrape this
  var url = fs.readFileSync('./app/data/domain.txt', 'utf8');

  request(url, function(error, response, html){
    if(!error){
      var $ = cheerio.load(html);
      var header;
      var json = { header : ""};

      $('.hero-message').filter(function(){
        var data = $(this);
        header = data.children().first().text();

        json.header = header;

      });
    } else {
      console.log(error);
    }

    fs.writeFile('./app/data/results.json', JSON.stringify(json, null, 4), function(err){
      console.log('File successfully written! - Check your project directory for the output.json file');
    });

    res.send('Check your console!')
  });
});

scraper.listen(4000);
console.log('Magic happens on port 4000');
exports = module.exports = scraper;

当我转到localhost:3000时,用户可以输入URL并点击提交,将它们重定向到localhost:3000 / results,并将URL记录在data / domain.txt中。

当我转到localhost:4000 / scrape时,刮刀激活,从domain.txt抓取域并擦除它。

我的问题是如何制作这个流畅的程序和/或如何自动激活刮刀而不是每次都进入localhost:4000 / scrape?我是Node.js和Express的新手,并意识到这是一个很难看的代码。

任何提示都将不胜感激。

1 个答案:

答案 0 :(得分:1)

没有必要为您要执行的操作保留两个单独的进程。你可以做的是移动刮板行动

scrapper.get("/scrape", function (req, res) {
    // code
});

到主app.js文件并提供端口3000中的所有内容,请确保在主要内容中包含来自scrapper的所有依赖项。此时,您可能希望了解如何使用node's module system来保持代码的分离和组织。

根据您的抓取过程需要多长时间,您可以执行以下操作之一:

  • 更改process操作以执行scrape操作此刻执行的工作,因此将域写入文件,然后转到另一个URL以从该文件中读取并启动在这个过程中,你会立即抓住域名并直接提供给刮刀。
  • 如果剪贴板需要很长时间并且您想要自动启动刮擦作业,则不希望它阻止您的应用程序或在请求期间抛出超时。您应该考虑实现工作队列机制。有很多方法可以做到这一点,正确的解决方案很大程度上取决于您的应用程序的预期用例。