【问题标题】:spawn child process inside for loop在 for 循环中生成子进程
【发布时间】:2021-04-13 04:29:23
【问题描述】:

下面是完整的工作代码,只有我用\\not working 评论的地方是我面临问题的地方。

这是在我的 nodejs 脚本中使用 spawn 进程的一般查询,我在 nodejs 脚本的 forloop 中创建和执行 spawn 进程。该forloop具有元素列表,在每个循环中将元素发送到python脚本,python脚本使用该元素执行一些操作并返回结果。

我正在做的是我将结果保存在 nodejs 脚本内的 javascript 数组中(但这没有执行)。而早些时候我能够显示返回的结果。

我想为每个元素创建生成过程,然后将其保存在 javascript 数组中,而不是显示来自 python 脚本的返回值。

Nodejs代码供参考,有for循环,见output_array = []我想把for循环的每个元素的spawn结果保存在这个输出数组中。

const express = require("express"),
  app = express();

var server = http.createServer(app);

const port = process.env.PORT || 3000
// Creates a server which runs on port 3000 and 
// can be accessed through localhost:3000 
app.listen(port, () => { 
    console.log(`server running on port at ${port}`); 
})

app.get('/', function(req, res){
    res.sendFile(path.join(__dirname,'index.html'));
});

app.post('/getscorelist', getscorelist);

function getscorelist(req, res){

    csvData = req.files.csvfile.data.toString('utf8');
    csvData = csvData.split(/\r\n/)
    output_array = []

    for (var i=1;i<csvData.length;i++){

        console.log(csvData[i])

        // Send request to python script
        var spawn = require('child_process').spawn;

        var process = spawn('python', ["-u", "./test.py", csvData[i].trim()])
    
        process.stdout.on('data', function(data){

            // Not working
            res.send("<p>"+data.toString()+"</p>")

        });

    }
}

上面代码的控制台输出如附件所示,您可以看到打印了 5 个相同的标题,我认为这与 csv 文件的第一个数字有关。由于数字不同,应该是不同的字符串。

将 csv 文件数据发送到 nodejs 脚本的 HTML 代码。此外,我之前在这个 html 文件中为 ajax 编写了代码,以将此请求发送到 nodejs api 并在 csv 文件中获取结果并生成链接,然后允许用户下载结果。为此我制作了一个 div 标签&lt;div id="linkforoutput"&gt;&lt;/div&gt;

<div class="multidiv">
            <form method="POST" enctype="multipart/form-data" action="/getscorelist">
                <p for="">Please upload csv file (having list of patent numbers):
                <br>
                <input type="file" style="cursor: pointer;" name="csvfile" id="csvfile" accept=".csv"></p><br><br>
                <button type="submit" id="submit_button" style="cursor: pointer;">Submit</button><br><br>         
            </form>
            <div id="linkforoutput"></div>
        </div>

下面是csv文件或nodejs脚本中for循环的元素

patent
9015616
9015617
9015618
9015699
7843093

让这个mainfile.py是python文件,执行如下

import requests
import sys
from bs4 import BeautifulSoup
import re

patent_number = sys.argv[1]
patent_number = patent_number.strip()

ur = "https://patents.google.com/patent/US"+str(patent_number)

ur = "https://patents.google.com/patent/US9015699"
headers = requests.utils.default_headers()
headers.update({
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
})
content = requests.get(ur, headers=headers)
soup = BeautifulSoup(content.text,'html.parser')
strin = soup.title.get_text().split("-")[1]

strin = strin.strip()

print(strin)

我正在尝试如下,我能够获得console.log(csvData[i]) 的控制台输出,但无法获得console.log(data.toString()) 的输出

app.post('/getscorelist', getscorelist);

function getscorelist(req, res){

    csvData = req.files.csvfile.data.toString('utf8');
    csvData = csvData.split(/\r\n/)
    output_array = []

    for (var i=1;i<csvData.length;i = i+1){


        console.log(csvData[i])

        // Send request to python script
        var spawn = require('child_process').spawn;

        var process = spawn('python', ["-u", "./test.py", csvData[i].trim()])
    
        process.stdout.on('data', function(data){

            console.log(data.toString())
    
        // data_csv_string = data.toString()
        // var strin = data_csv_string.trim()
        // strin = strin.replace(/(\r)/gm, "");
        // output_array.push(strin)
        // res.send(200)

        });

        
    }
}

【问题讨论】:

  • 我很震惊,我非常接近解决方案,但在这个 SO 中没有得到正确的建议
  • @kabanus 请看我更新了代码

标签: python node.js


【解决方案1】:

我认为解决这个问题的更简洁的方法是使用由 ZeroMQ 等提供的 REQUEST-RESPONSE / RPC 模式,您可以使用它来将您的 express.js 服务器与基于 python 的 beautifulsoup 服务进行通信。在我看来,结果将更加模块化和可重用。 python virtualenv 的管理将保持独立。否则,将难以管理和触发正确的解释器和相关的环境变量。

这里有几个链接:

例如,以下是 ZeroMQ 官方指南中 node.js 中 RPC 客户端的代码 sn-p:

// Hello World client
// Connects REQ socket to tcp://localhost:5555
// Sends "Hello" to server.

var zmq = require('zeromq');

// socket to talk to server
console.log("Connecting to hello world server...");
var requester = zmq.socket('req');

var x = 0;
requester.on("message", function(reply) {
  console.log("Received reply", x, ": [", reply.toString(), ']');
  x += 1;
  if (x === 10) {
    requester.close();
    process.exit(0);
  }
});

requester.connect("tcp://localhost:5555");

for (var i = 0; i < 10; i++) {
  console.log("Sending request", i, '...');
  requester.send("Hello");
}

process.on('SIGINT', function() {
  requester.close();
});

这里是python中对应的服务器:

#
#   Hello World server in Python
#   Binds REP socket to tcp://*:5555
#   Expects b"Hello" from client, replies with b"World"
#

import time
import zmq

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:5555")

while True:
    #  Wait for next request from client
    message = socket.recv()
    print("Received request: %s" % message)

    #  Do some 'work'
    time.sleep(1)

    #  Send reply back to client
    socket.send(b"World")

我认为上面的例子也可以修改以适应当前的问题。

【讨论】:

  • 嗨,我没听明白
  • 嗨,你能帮我吗
  • 你好@Nickjones,我已经发布了对我之前答案的更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 2020-02-03
  • 1970-01-01
  • 2018-06-15
相关资源
最近更新 更多