多年来,我使用 Chrome DevTools 和 Network 选项卡从 google.translate.com 提取声音。单击“网络”选项卡中的声音按钮时,会出现一个 mp3 文件。我只是单击该按钮并下载了用于教育目的的文件。
现在只有 XHR 类型的文件,像 JS 数组中的字符串一样,方括号内有无数的字符序列。而且页面本身相当复杂。
新环境下如何提取声音?
php 代码执行此操作:
<?php
$lang = 'en';
$text = 'hello world';
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://translate.google.com/_/TranslateWebserverUi/data/batchexecute',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => http_build_query([
'f.req' => json_encode([
[
[
'jQ1olc',
json_encode([
$text,
$lang,
null,
json_encode(null),
]),
null,
'generic',
]
]
]),
]),
]);
$response = curl_exec($curl);
curl_close($curl);
if ($response && preg_match('#//NE[^\\\\]+#', $response, $matches)) {
file_put_contents('test.mp3', base64_decode($matches[0]));
}
else {
echo "error\n";
}
xhr
请求到batchexecute?rpcids...
,这将是几个kB,这种xhr
响应包含以base64编码的mp3。"[\"//NExAAR...VV\"]"
,从括号和引号中清除该字符串以获得类似//NExAAR...VV
的内容并将其保存到sound.base64
文件中.sound.base64
中的文本解码为 mp3 文件:base64 -d sound.base64 > 1.mp3
mpg123 1.mp3
或
使用 https://soundoftext.com/ 或测试 https://github.com/soimort/translate-shell#usage 音频选项。
更新:
curl ... | grep -oP '\[\["wrb.fr","jQ1olc","\[\\"\K(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?' | base64 -d > /tmp/123.mp3
感谢@alukardd 提供代码。
可以在 Chrome DevTools 中右键单击请求:复制 => 复制为 cURL。
感谢@fjewo 提供信息。
这里是Python中的公元2023年工作示例,用于从谷歌翻译中获取mp3:
import re
import requests
import json
import base64
lang = 'en'
text = 'hello world'
data = {
'f.req': json.dumps([
[
[
'jQ1olc',
json.dumps([
text,
lang,
None,
json.dumps(None),
]),
None,
'generic',
]
]
]),
}
response = requests.post('https://translate.google.com/_/TranslateWebserverUi/data/batchexecute', data=data)
if response.status_code == 200:
match = re.search(r'//OE[^\\\\]+', response.text)
if match:
with open('test.mp3', 'wb') as f:
f.write(base64.b64decode(match.group(0)))
else:
print('error Match')
else:
print('error HTTP')
快速替代方案 - 如果您使用的是 Mac OSx,您还可以安装 SoundFlower 并将音频输出重新路由到 DAW 或 QuickTime 播放器。
Python 解决方案的 JavaScript (Node) 版本,已于 2024 年 11 月测试运行:
const fs = require('fs').promises;
async function gtranslate_tts(text, lang) {
let data = [[[
'jQ1olc',
JSON.stringify([
text,
lang,
null,
"null",
]),
null,
'generic',
]]];
let response = await fetch('https://translate.google.com/_/TranslateWebserverUi/data/batchexecute', {
method: "POST",
body: new URLSearchParams([["f.req", JSON.stringify(data)]]),
});
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
let resptext = await response.text();
let mp3b64 = resptext.match(/\/\/OE[^\\]+/);
if (!mp3b64) {
throw new Error("mp3 not found in response");
}
return Buffer.from(mp3b64[0], 'base64');
}
async function main() {
/* Demo of how to use gtranslate_tts */
let res = await gtranslate_tts("hello world", "en");
await fs.writeFile("test.mp3", res);
}
main();