我有一个post请求来生成一个子进程以运行discord_bot.py脚本并向其传递一个变量。
当我从终端运行脚本时,它运行得很好。但是,当我在我的NodeIdeJS应用程序中通过post路由运行它时,它总是在某个特定的点崩溃。
我已经张贴如下:
1.从我的server.js文件中发布路由代码。
1.来自我的discord_bot.py脚本的代码,**!!!!!!**在失败点。
1.我在控制台中遇到的错误。
从server.js发送路由
const mysql = require("mysql");
const discordbot = require("./config/discordbot.js");
const port = process.env.PORT || 3001;
const fs = require("fs-extra");
const router = express.Router();
const axios = require("axios");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
app.use(cors());
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const spawner = require("child_process").spawn;
const promptCommand = "test output command";
app.post("/runPythonScript", (req, res) => {
const pythonProcess = spawner("python", [
path.join(__dirname, "public/py/discord_bot.py"),
promptCommand,
]);
console.log("Data sent to python script:", promptCommand);
pythonProcess.stdout.on("data", (data) => {
console.log("Data send back from python script:", data.toString());
res.json({ message: "Python script is running" });
});
});
discord_bot.py中带有**!!!!!!**的代码位于故障点。
import sys
import os
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.relative_locator import locate_with
from dotenv import load_dotenv
load_dotenv()
# Initialize the browser instance
# path_to_chromedriver = 'C:/Users/mrthe/bootcamp/pydiscordbrowser/chromedriver.exe'
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
options = webdriver.ChromeOptions()
options.add_argument('--headless=False')
# Navigate to Discord
driver.get('https://discord.com/login')
time.sleep(2)
# Find the email and password fields and fill 'em in
time.sleep(2)
dlEMAIL = os.getenv('dlEMAIL')
dlPASSWORD = os.getenv('dlPASSWORD')
jxEMAIL = os.getenv('jxEMAIL')
jxPASSWORD = os.getenv('jxPASSWORD')
jxPyEMAIL = os.getenv('jxPyEMAIL')
jxPyPASSWORD = os.getenv('jxPyPASSWORD')
email_field = driver.find_element(By.NAME, 'email')
email_field.send_keys(jxPyEMAIL)
password_field = driver.find_element(By.NAME, 'password')
password_field.send_keys(jxPyPASSWORD)
# Find the login button on the login form and click it
time.sleep(1)
loginButton = driver.find_element(locate_with(By.TAG_NAME, "div").above({
By.CLASS_NAME: "needAccount-MrvMN7"}).below({By.CLASS_NAME: "contents-3ca1mk"}))
loginButton.click()
print("##### Made it through login process")
sys.stdout.flush()
# Navigate to server and channel via URL
time.sleep(5)
driver.get("https://discord.com/channels/1063538236[REDACTED]/106353823690[REDACTED]")
print("##### Made it to the proper channel in the DL server")
sys.stdout.flush()
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Post in the channel
time.sleep(3)
# Get the active element
active_element = driver.execute_script("return document.activeElement")
print("##### got active element via script execution")
sys.stdout.flush()
time.sleep(3)
# Print the element to the console
print(active_element.get_attribute("outerHTML"))
print("#### printed active element to console")
sys.stdout.flush()
time.sleep(3)
# Send input to the active element
print("##### made it to first prompts variables blocks")
sys.stdout.flush()
text1 = "test output 1"
text2 = "test output 2"
text3 = "test output 3"
data_to_send_back = "Message from python script: Hello."
print("##### made it to commented out inputs/outputs")
sys.stdout.flush()
input = sys.argv\[1\]
output = data_to_send_back
print(output)
sys.stdout.flush()
print("##### made it to the send_keys list")
sys.stdout.flush()
active_element.send_keys(text1)
time.sleep(300/1000)
active_element.send_keys(Keys.SPACE)
time.sleep(300/1000)
active_element.send_keys(Keys.ENTER)
终端错误
[29220:31768:0118/170808.365:ERROR:cert_issuer_source_aia.cc(34)] Error parsing cert retrieved from AIA (as DER):
ERROR: Couldn't read tbsCertificate as SEQUENCE
ERROR: Failed parsing Certificate
Data send back from python script: ##### Made it to the proper channel in the DL server
node:_http_outgoing:644
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
∮我尝试过的事∮
我想我调用这个论证的方式可能有问题,所以为了测试,我完全删除了下面的代码块。
sys.stdout.flush()
input = sys.argv[1]
output = data_to_send_back
print(output)
这并没有改变行为。脚本仍然在完全相同的点崩溃(在上面的代码中用**!!!!!**标记)。
然而,如果我从终端而不是从post路径运行脚本,它运行得非常好。
2.
我实施了迈克尔M的建议,从他的评论和更新我的邮政路线代码如下。
app.post("/runPythonScript", async (req, res) => {
const pythonProcess = spawner("python", [
path.join(__dirname, "public/py/discord_bot.py"),
promptCommand,
]);
console.log("Data sent to python script:", promptCommand);
let data = "";
pythonProcess.stdout.on("data", (part) => (data += part));
await new Promise((resolve) => pythonProcess.stdout.on("close", resolve));
console.log("Data send back from python script:", data.toString());
res.json({ message: "Python finished", data: data });
});
我们已经取得了进展,因为我现在在终端中得到了不同的错误,但脚本仍然在同一点崩溃。
这些是我现在收到的错误。
Error parsing cert retrieved from AIA (as DER):
ERROR: Couldn't read tbsCertificate as SEQUENCE
ERROR: Failed parsing Certificate
Data send back from python script: ##### Made it through login process
##### Made it to the proper channel in the DL server
##### got active element via script execution
1条答案
按热度按时间mxg2im7a1#
问题出在您的服务器上。您的
pythonProcess.stdout.on("data"
处理程序可以多次运行,每次都使用新数据,但您只能调用res.json()
一次,因为正如错误所述,它设置标头。请尝试使用promise和"close"
事件:这将等待向变量添加任何新数据,然后等待进程结束。一旦进程结束,它将打印累积的数据并将其发送回客户端。