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

使用Apertium API批量转换网站多语言内容遇异常求助

问题:Apertium API转换带HTML文本效果不稳定的排查与解决

我尝试使用apertium.org提供的API将网站部分内容从一种语言转换为另一种语言,但转换效果不佳。具体流程为:先构建包含带HTML代码长句的变量数组,目标是将这些长句转换为外文,每种语言最终生成对应JSON格式的htm文件,在PHP脚本中调用gettextinlanguage("por","variable")即可获取对应文本,但结果时好时坏。我发现若使用换行符作为分隔符,转换效果极差;尝试用HTML注释作为分隔符也无明显改善。查看PHP错误日志未得到有效信息。请问是该语言转换器本身问题,还是我的实现方式有误?另外无法直接传入JSON格式数据,因为API不支持。相关代码如下:

function gettextinlanguage($lang, $txt)
{
    $res = json_decode(file_get_contents(langfol() . "/" . $lang . ".htm"), true);
    return $res[$txt];
}

function langfol()
{
    return "/path/to/languagefiles";
}

function loadwords()
{
    //our words.
    $words = array(
        "Ball" => 'This <b ID="English">ball</p> is bouncy',
        "Apple" => 'Apples <i ID="England">are</i> red'
    );
}

function buildbaseconv()
{
    //build our english data in JSON format
    $fol = langfol();
    $w = loadwords();
    $ww = '';
    foreach ($w as $n => $v) {
        $ww .= $v . "<!--delim1-->";
    }
    $x = fopen($fol . "/eng.htm", "w");
    fwrite($x, rawlangtojson($ww));
    fclose($x);
}


function rawlangfromjson($fi)
{
    $d = json_decode($fi, true);
    if (!is_array($d)) {
        echo "ERROR: No Array
";
        return;
    }
    $ww = '';
    foreach ($d as $naa => $vaa) {
        $ww .= $vaa . "<!--delim1-->";
    }
    return $ww;
}

function rawlangtojson($fi)
{
    if (strpos($fi, "<!--delim1-->") === false) {
        echo "ERROR: data delimiter not received!";
        return;
    }
    $valz = explode("<!--delim1-->", $fi);
    $c = 0;
    $w = loadwords('', 0);
    foreach ($w as $naa => $vaa) {
        if (!isset($valz[$c])) {
            echo "ERROR: Value offset " . $c . " not found
";
            break;
        }
        $wds[$naa] = $valz[$c];
        $c++;
    }
    return json_encode($wds, true);
}

function test()
{
    buildbaseconv();
    $fol = langfol();
    //do language conversion
    $sourcelang = 'eng';
    $destlang = 'por';
    //our language files are JSON encoded but
    //the remote server cant handle JSON so we have to
    //convert it to values with delimiters
    $data = rawlangfromjson(file_get_contents($fol . "/" . $sourcelang . ".htm"));
    //Make the file acceptable for the remote translator
    $f = fopen($fol . "/Lfr.htm", "w");
    fwrite($f, $data);
    fclose($f);
    langexec($fol, $sourcelang, $destlang);
    //Convert the result back to JSON
    $data = rawlangtojson(file_get_contents($fol . "/Lto.htm"));
    //and save it as its own language file
    $f = fopen($fol . "/" . $destlang . ".htm", "w");
    fwrite($f, $data);
    fclose($f);
}


function langexec($fol, $fr, $to)
{
    //actual language converter
    system("curl -sk --form 'file=@" . $fol . "/Lfr.htm' 'https://www.apertium.org/apy/translateDoc?markUnknown=no\&langpair=" . $fr . "|" . $to . "' > " . $fol . "/Lto.htm");
}

我已尝试更换分隔符,但问题仍未解决。


排查与分析

1. 实现逻辑的核心问题

你当前的方案是把多个带HTML的文本用分隔符拼接成单个文件传给API,再拆分还原成JSON。但Apertium的文档翻译接口是针对完整文档设计的,它会把整个文件内容当作连续文本处理,而非多个独立条目,这会导致:

  • 分隔符可能被API的分词/翻译逻辑误处理(比如把HTML注释当成内容的一部分,或分隔符前后的文本被当成连续句子翻译,破坏语义)
  • 带HTML标签的文本连续拼接后,API无法识别每个条目是独立单元,翻译时上下文混乱,导致结果时好时坏

2. API本身的限制

Apertium的翻译API对HTML的支持有限,更适合处理结构简单的纯文本或基础HTML文档。如果你的文本里有嵌套标签、不闭合标签(比如示例中<b>未闭合却用了</p>),会进一步干扰API的解析,加剧翻译异常。


解决方案

1. 改为逐个条目调用API

放弃批量拼接的方式,对每个文本条目单独调用Apertium的文本翻译接口(而非文档翻译接口),确保每个条目独立处理,避免上下文干扰。示例修改:

function translateSingleText($sourceLang, $targetLang, $text) {
    $url = "https://www.apertium.org/apy/translate";
    $data = http_build_query([
        'langpair' => "$sourceLang|$targetLang",
        'q' => $text,
        'markUnknown' => 'no'
    ]);
    
    $options = [
        'http' => [
            'header' => "Content-type: application/x-www-form-urlencoded\r\n",
            'method' => 'POST',
            'content' => $data
        ]
    ];
    
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    $response = json_decode($result, true);
    
    return $response['responseData']['translatedText'] ?? $text;
}

// 修改test函数,逐个翻译条目
function test() {
    $fol = langfol();
    $sourceLang = 'eng';
    $targetLang = 'por';
    
    // 加载原始英文数据
    $words = loadwords();
    $translatedWords = [];
    
    foreach ($words as $key => $text) {
        $translatedWords[$key] = translateSingleText($sourceLang, $targetLang, $text);
    }
    
    // 保存为目标语言JSON文件
    file_put_contents($fol . "/$targetLang.htm", json_encode($translatedWords));
}

2. 修复HTML标签问题

确保输入的HTML标签合法闭合,比如把示例中的'This &lt;b ID=&quot;English&quot;&gt;ball&lt;/p&gt; is bouncy'改为'This &lt;b ID=&quot;English&quot;&gt;ball&lt;/b&gt; is bouncy',避免API解析HTML时出错。

3. 优化分隔符方案(若坚持批量)

如果必须使用文档翻译接口,改用API无法识别、且不会出现在文本中的特殊分隔符,比如|||SEPARATOR|||,同时确保每个条目是独立段落(用换行分隔):

// 修改拼接逻辑
function rawlangfromjson($fi) {
    $d = json_decode($fi, true);
    if (!is_array($d)) {
        echo "ERROR: No Array\n";
        return;
    }
    $ww = '';
    foreach ($d as $naa => $vaa) {
        $ww .= $vaa . "\n|||SEPARATOR|||\n";
    }
    return $ww;
}

// 修改拆分逻辑
function rawlangtojson($fi) {
    $valz = explode("\n|||SEPARATOR|||\n", $fi);
    // 后续逻辑不变...
}

内容的提问来源于stack exchange,提问作者mike_s

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:37:03