Google a mis en place un captcha pour empêcher les gens d'accéder à l'API de traduction TTS https://translate.google.com/translate_tts?ie=UTF-8&q=test&tl=zh-TW . Je l'utilisais dans mon application mobile. Maintenant, il ne retourne rien. Comment contourner le captcha?
Ajoutez le qualificatif '& client = tw-ob' à la fin de votre requête. https://translate.google.com/translate_tts?ie=UTF-8&q=test&tl=zh-TW&client=tw-ob
Cette réponse ne fonctionne plus de manière cohérente. Votre adresse IP sera temporairement bloquée par Google si vous en abusez trop.
il y a 3 problèmes principaux:
résumer:
function generateGoogleTTSLink(q, tl, tkk) {
var tk = calcHash(q, tkk);
return `https://translate.google.com/translate_tts?ie=UTF-8&total=1&idx=0&client=t&ttsspeed=1&tl=${tl}&tk=${tk}&q=${q}&textlen=${q.length}`;
}
generateGoogleTTSLink('ciao', 'it', '410353.1336369826');
// see definition of "calcHash" in the bottom of this comment.
=> pour mettre la main sur un TKK, vous pouvez ouvrir le site Web Google Translate, puis taper "TKK" dans la console des outils de développement (par exemple: "410353.1336369826").
REMARQUE: la valeur TKK change toutes les heures, et donc, les anciens TKK peuvent être bloqués à un moment donné, et leur rafraîchissement peut être nécessaire (bien que jusqu'à présent, il semble que les anciennes clés puissent fonctionner pendant longtemps).
si vous souhaitez actualiser périodiquement TKK, il peut être automatisé assez facilement, mais pas si vous exécutez votre code à partir du navigateur.
vous pouvez trouver une implémentation complète de NodeJS ici: https://github.com/guyrotem/google-translate-server . il expose une API TTS minimale (requête, langue) et est déployé sur un serveur Heroku gratuit, vous pouvez donc le tester en ligne si vous le souhaitez.
function shiftLeftOrRightThenSumOrXor(num, opArray) {
return opArray.reduce((acc, opString) => {
var op1 = opString[1]; // '+' | '-' ~ SUM | XOR
var op2 = opString[0]; // '+' | '^' ~ SLL | SRL
var xd = opString[2]; // [0-9a-f]
var shiftAmount = hexCharAsNumber(xd);
var mask = (op1 == '+') ? acc >>> shiftAmount : acc << shiftAmount;
return (op2 == '+') ? (acc + mask & 0xffffffff) : (acc ^ mask);
}, num);
}
function hexCharAsNumber(xd) {
return (xd >= 'a') ? xd.charCodeAt(0) - 87 : Number(xd);
}
function transformQuery(query) {
for (var e = [], f = 0, g = 0; g < query.length; g++) {
var l = query.charCodeAt(g);
if (l < 128) {
e[f++] = l; // 0{l[6-0]}
} else if (l < 2048) {
e[f++] = l >> 6 | 0xC0; // 110{l[10-6]}
e[f++] = l & 0x3F | 0x80; // 10{l[5-0]}
} else if (0xD800 == (l & 0xFC00) && g + 1 < query.length && 0xDC00 == (query.charCodeAt(g + 1) & 0xFC00)) {
// that's pretty rare... (avoid ovf?)
l = (1 << 16) + ((l & 0x03FF) << 10) + (query.charCodeAt(++g) & 0x03FF);
e[f++] = l >> 18 | 0xF0; // 111100{l[9-8*]}
e[f++] = l >> 12 & 0x3F | 0x80; // 10{l[7*-2]}
e[f++] = l & 0x3F | 0x80; // 10{(l+1)[5-0]}
} else {
e[f++] = l >> 12 | 0xE0; // 1110{l[15-12]}
e[f++] = l >> 6 & 0x3F | 0x80; // 10{l[11-6]}
e[f++] = l & 0x3F | 0x80; // 10{l[5-0]}
}
}
return e;
}
function normalizeHash(encondindRound2) {
if (encondindRound2 < 0) {
encondindRound2 = (encondindRound2 & 0x7fffffff) + 0x80000000;
}
return encondindRound2 % 1E6;
}
function calcHash(query, windowTkk) {
// STEP 1: spread the the query char codes on a byte-array, 1-3 bytes per char
var bytesArray = transformQuery(query);
// STEP 2: starting with TKK index, add the array from last step one-by-one, and do 2 rounds of shift+add/xor
var d = windowTkk.split('.');
var tkkIndex = Number(d[0]) || 0;
var tkkKey = Number(d[1]) || 0;
var encondingRound1 = bytesArray.reduce((acc, current) => {
acc += current;
return shiftLeftOrRightThenSumOrXor(acc, ['+-a', '^+6'])
}, tkkIndex);
// STEP 3: apply 3 rounds of shift+add/xor and XOR with they TKK key
var encondingRound2 = shiftLeftOrRightThenSumOrXor(encondingRound1, ['+-3', '^+b', '+-f']) ^ tkkKey;
// STEP 4: Normalize to 2s complement & format
var normalizedResult = normalizeHash(encondingRound2);
return normalizedResult.toString() + "." + (normalizedResult ^ tkkIndex)
}
// usage example:
var tk = calcHash('hola', '409837.2120040981');
console.log('tk=' + tk);
// OUTPUT: 'tk=70528.480109'
Tout d'abord, pour éviter le captcha, vous devez définir un agent utilisateur approprié comme:
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv: 46.0) Gecko/20100101 Firefox/46.0"
Pour ne pas être bloqué, vous devez fournir un jeton approprié (paramètre get "tk") pour chaque requête.
. pour récupérer votre jeton simplement en observant des demandes similaires profondes pour traduire la page (avec votre texte dans l'url).
Vous pouvez lire l'heure du jeton en récupérant "tk =" à partir de la sortie de ce code simple avec phantomjs:
"use strict";
var page = require('webpage').create();
var system = require('system');
var args = system.args;
if (args.length != 2) { console.log("usage: "+args[0]+" text"); phantom.exit(1); }
page.onConsoleMessage = function(msg) { console.log(msg); };
page.onResourceRequested = function(request) { console.log('Request ' + JSON.stringify(request, undefined, 4)); };
page.open("https://translate.google.it/?hl=it&tab=wT#fr/it/"+args[1], function(status) {
if (status === "success") { phantom.exit(0); }
else { phantom.exit(1); }
});
donc à la fin vous pouvez obtenir votre discours avec quelque chose comme:
wget -U "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv: 46.0) Gecko/20100101 Firefox/46.0" " http://translate.google.com/translate_tts?ie= UTF-8 & tl = it & tk = 52269.458629 & q = ciao & client = t "-O ciao.mp3
(les jetons sont probablement basés sur le temps, donc ce lien peut ne pas fonctionner demain)
Vous pouvez également essayer ce format:
passez le format q = urlencode de votre langue (en JavaScript, vous pouvez utiliser la fonction encodeURI () & PHP a la fonction rawurlencode ())
passer tl = nom abrégé de la langue (supposons que bangla = bn)
Maintenant, essayez ceci: