You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下直接执行正常,Java调用含Selenium的Python脚本失败如何解决?

解决Java调用Python脚本时ChromeDriver意外退出(状态码-11)的问题

问题背景

我有一个用pyhtml2pdf实现的HTML转PDF的Python脚本:

import os
import sys
from pyhtml2pdf import converter

def convert_html_to_pdf(html_path, pdf_path):
    absolute_html_path = os.path.abspath(html_path)
    converter.convert(f'file:///{absolute_html_path}', pdf_path, 60, False, 0, False)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: python3 test.py <html_path> <pdf_path>")
    else:
        html_path = sys.argv[1]
        pdf_path = sys.argv[2]
        convert_html_to_pdf(html_path, pdf_path)

在Linux服务器上直接执行以下命令完全正常,能生成PDF:

DISPLAY=:99 python3 test.py 298.html 298.pdf

但通过Java程序调用时:

String comds = "DISPLAY=:99 python3 test.py 298.html 298.pdf";
Runtime.getRuntime().exec(comds);

出现错误:

2024-09-27 11:33:14 - ERROR>Traceback (most recent call last):
2024-09-27 11:33:14 - ERROR>  File "test.py", line 15, in <module>
2024-09-27 11:33:14 - ERROR>    convert_html_to_pdf(html_path, pdf_path)
2024-09-27 11:33:14 - ERROR>  File "test.py", line 7, in convert_html_to_pdf
2024-09-27 11:33:14 - ERROR>    converter.convert(f'file:///{absolute_html_path}', pdf_path, 20, False, 0, False)
2024-09-27 11:33:14 - ERROR>  File "/usr/local/lib/python3.6/site-packages/pyhtml2pdf/converter.py", line 39, in convert
2024-09-27 11:33:14 - ERROR>    source, timeout, install_driver, print_options)
2024-09-27 11:33:14 - ERROR>  File "/usr/local/lib/python3.6/site-packages/pyhtml2pdf/converter.py", line 79, in __get_pdf_from_html
2024-09-27 11:33:14 - ERROR>    driver = webdriver.Chrome(options=webdriver_options)
2024-09-27 11:33:14 - ERROR>  File "/usr/local/lib/python3.6/site-packages/selenium/webdriver/chrome/webdriver.py", line 73, in __init__
2024-09-27 11:33:14 - ERROR>    self.service.start()
2024-09-27 11:33:14 - ERROR>  File "/usr/local/lib/python3.6/site-packages/selenium/webdriver/common/service.py", line 98, in start
2024-09-27 11:33:14 - ERROR>    self.assert_process_still_running()
2024-09-27 11:33:14 - ERROR>  File "/usr/local/lib/python3.6/site-packages/selenium/webdriver/common/service.py", line 111, in assert_process_still_running
2024-09-27 11:33:14 - ERROR>    % (self.path, return_code)
2024-09-27 11:33:14 - ERROR>selenium.common.exceptions.WebDriverException: Message: Service chromedriver unexpectedly exited. Status code was: -11

当前ChromeDriver版本:ChromeDriver 129.0.6668.70


解决方案

1. 修正Java命令执行方式

Runtime.exec()不会像shell那样解析DISPLAY=:99这种环境变量赋值语句,换两种方式处理:

方式一:通过shell执行完整命令

把命令交给shell解析,确保环境变量赋值生效:

String comds = "/bin/sh -c 'DISPLAY=:99 python3 test.py 298.html 298.pdf'";
Runtime.getRuntime().exec(comds);

如果是bash环境,也可以用/bin/bash -c ...。

方式二:单独设置环境变量

用exec的重载方法,将DISPLAY加入进程环境:

String[] cmd = {"python3", "test.py", "298.html", "298.pdf"};
// 获取当前环境变量并添加DISPLAY
Map<String, String> env = new HashMap<>(System.getenv());
env.put("DISPLAY", ":99");
// 转换为环境变量数组
String[] envArray = env.entrySet().stream()
    .map(e -> e.getKey() + "=" + e.getValue())
    .toArray(String[]::new);
// 执行命令
Runtime.getRuntime().exec(cmd, envArray);

2. 给ChromeDriver添加无头模式参数

pyhtml2pdf底层依赖Selenium,Java进程的图形环境可能存在异常,强制开启无头模式可规避这类问题。修改Python脚本,自定义ChromeOptions:

import os
import sys
from pyhtml2pdf import converter
from selenium.webdriver.chrome.options import Options

def convert_html_to_pdf(html_path, pdf_path):
    absolute_html_path = os.path.abspath(html_path)
    # 配置Chrome无头模式及Linux适配参数
    chrome_options = Options()
    chrome_options.add_argument("--headless=new")
    chrome_options.add_argument("--no-sandbox")  # 解决Linux权限限制
    chrome_options.add_argument("--disable-dev-shm-usage")  # 避免临时空间不足
    # 传入自定义配置
    converter.convert(f'file:///{absolute_html_path}', pdf_path, 60, False, 0, False, chrome_options=chrome_options)

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("Usage: python3 test.py <html_path> <pdf_path>")
    else:
        html_path = sys.argv[1]
        pdf_path = sys.argv[2]
        convert_html_to_pdf(html_path, pdf_path)

3. 检查权限与环境一致性

  • 确保Java进程有权访问:Xvfb(若DISPLAY:99是Xvfb实例)、chromedriver、Chrome浏览器、HTML输入文件、PDF输出路径。
  • 对比命令行用户与Java进程用户的环境变量,比如PATH是否包含chromedriver路径,可在Python脚本中打印环境变量排查:
    import os
    print(os.environ)
    

4. 验证Chrome与ChromeDriver版本匹配

确认服务器上Chrome浏览器版本与ChromeDriver主版本号完全一致(比如Chrome 129对应ChromeDriver 129.x)。执行google-chrome --version查看浏览器版本,不匹配则下载对应版本的ChromeDriver替换。


内容的提问来源于stack exchange,提问作者海绵宝宝

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:05:09