Last active
February 15, 2024 13:21
-
-
Save vielhuber/b7739bf50b2edcf636c43a8f8910def9 to your computer and use it in GitHub Desktop.
Google Translate API Hacking #knowhow #tools
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Bp(a, b) { | |
var c = b.split("."); | |
b = Number(c[0]) || 0; | |
for (var d = [], e = 0, f = 0; f < a.length; f++) { | |
var h = a.charCodeAt(f); | |
128 > h ? d[e++] = h : (2048 > h ? d[e++] = h >> 6 | 192 : (55296 == (h & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ? (h = 65536 + ((h & 1023) << 10) + (a.charCodeAt(++f) & 1023), d[e++] = h >> 18 | 240, d[e++] = h >> 12 & 63 | 128) : d[e++] = h >> 12 | 224, d[e++] = h >> 6 & 63 | 128), d[e++] = h & 63 | 128) | |
} | |
a = b; | |
for (e = 0; e < d.length; e++) a += d[e], a = Ap(a, "+-a^+6"); | |
a = Ap(a, "+-3^+b+-f"); | |
a ^= Number(c[1]) || 0; | |
0 > a && (a = (a & 2147483647) + 2147483648); | |
c = a % 1E6; | |
return c.toString() + | |
"." + (c ^ b) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Tr.prototype.translate = function (a, b, c, d, e, f, h, k) { | |
var l = this, | |
m = this.a.wc(a), | |
n = { | |
q: b, | |
sl: c, | |
tl: d | |
}; | |
this.h.sp && 0 == this.h.sp.indexOf("nmt") || (n.sp = "nmt"); | |
n.tc = e; | |
f && (n.ctt = 1); | |
h && (n.dom = 1); | |
k && (n.sr = 1); | |
n[Dp()] = Bp(b.join(""), Hq); | |
return this.s ? this.s.b().then(function (r) { | |
null != r && (n.jwtt = r, n.rurl = location.hostname); | |
return l.a.na.send(n, C(Wr(m), l)) | |
}, function (r) { | |
r && l.Vb && l.Vb(r) | |
}) : this.a.na.send(n, m) | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Hq = function () { | |
function a(d) { | |
return function () { | |
return d | |
} | |
} | |
var b = String.fromCharCode(107), | |
c = a(String.fromCharCode(116)); | |
b = a(b); | |
c = [c(), c()]; | |
c[1] = b(); | |
return yq["_c" + c.join(b())] || "" | |
}(), |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Hq = function () { | |
var b = 'k', | |
c = 't'; | |
c = [c, c]; | |
c[1] = b(); | |
return yq['_c' + c.join(b())] || '' | |
}(), |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Hq = function () { | |
return yq['_ctkk'] || '' | |
}(), |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var yq = window.google && google.translate && google.translate._const; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log(window.google.translate._const._ctkk); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GURL TranslateScript::GetTranslateScriptURL() { | |
GURL translate_script_url; | |
// Check if command-line contains an alternative URL for translate service. | |
const base::CommandLine& command_line = | |
*base::CommandLine::ForCurrentProcess(); | |
if (command_line.HasSwitch(translate::switches::kTranslateScriptURL)) { | |
translate_script_url = GURL(command_line.GetSwitchValueASCII( | |
translate::switches::kTranslateScriptURL)); | |
if (!translate_script_url.is_valid() || | |
!translate_script_url.query().empty()) { | |
LOG(WARNING) << "The following translate URL specified at the " | |
<< "command-line is invalid: " | |
<< translate_script_url.spec(); | |
translate_script_url = GURL(); | |
} | |
} | |
// Use default URL when command-line argument is not specified, or specified | |
// URL is invalid. | |
if (translate_script_url.is_empty()) | |
translate_script_url = GURL(kScriptURL); | |
translate_script_url = net::AppendQueryParameter( | |
translate_script_url, | |
kCallbackQueryName, | |
kCallbackQueryValue); | |
translate_script_url = net::AppendQueryParameter( | |
translate_script_url, | |
kAlwaysUseSslQueryName, | |
kAlwaysUseSslQueryValue); | |
translate_script_url = net::AppendQueryParameter( | |
translate_script_url, | |
kCssLoaderCallbackQueryName, | |
kCssLoaderCallbackQueryValue); | |
translate_script_url = net::AppendQueryParameter( | |
translate_script_url, | |
kJavascriptLoaderCallbackQueryName, | |
kJavascriptLoaderCallbackQueryValue); | |
translate_script_url = AddHostLocaleToUrl(translate_script_url); | |
translate_script_url = AddApiKeyToUrl(translate_script_url); | |
return translate_script_url; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const char TranslateScript::kScriptURL[] = | |
"https://translate.googleapis.com/translate_a/element.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function _setupNS(b) { | |
b = b.split("."); | |
for (var a = window, c = 0; c < b.length; ++c) a.hasOwnProperty ? a.hasOwnProperty(b[c]) ? a = a[b[c]] : a = a[b[c]] = {} : a = a[b[c]] || (a[b[c]] = {}); | |
return a | |
} | |
window.addEventListener && "undefined" == typeof document.readyState && window.addEventListener("DOMContentLoaded", function () { | |
document.readyState = "complete" | |
}, !1); | |
if (_isNS('google.translate.Element')) { | |
return | |
}(function () { | |
var c = _setupNS('google.translate._const'); | |
c._cest = gtConstEvalStartTime; | |
gtConstEvalStartTime = undefined; | |
c._cl = 'de'; | |
c._cac = ''; | |
c._cam = ''; | |
c._ctkk = '440159.776620256'; | |
var h = 'translate.googleapis.com'; | |
var s = (true ? 'https' : window.location.protocol == 'https:' ? 'https' : 'http') + '://'; | |
var b = s + h; | |
c._pah = h; | |
c._pas = s; | |
c._pbi = b + '/translate_static/img/te_bk.gif'; | |
c._pci = b + '/translate_static/img/te_ctrl3.gif'; | |
c._pli = b + '/translate_static/img/loading.gif'; | |
c._plla = h + '/translate_a/l'; | |
c._pmi = b + '/translate_static/img/mini_google.png'; | |
c._ps = b + '/translate_static/css/translateelement.css'; | |
c._puh = 'translate.google.com'; | |
_loadCss(c._ps); | |
_loadJs(b + '/translate_static/js/element/main_de.js'); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GURL AddApiKeyToUrl(const GURL& url) { | |
return net::AppendQueryParameter(url, kApiKeyName, google_apis::GetAPIKey()); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if !defined(GOOGLE_API_KEY) | |
#define GOOGLE_API_KEY DUMMY_API_TOKEN | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
x.Pf = function (a, b) { | |
b.g && this.l.remove(b.f); | |
if (!this.b) return !1; | |
if (this.l.has(b.ea(), !1)) { | |
var c = this.l; | |
if (c.has(b.f, !1)) { | |
var d = b.f, | |
e = c.a[d]; | |
e || (e = c.b[d], c.a[d] = e); | |
b.b = e; | |
b.K = !0 | |
} else c.remove(b.f), b.g = !0; | |
zt(b) | |
} else if (c = this.l, b.g) c.remove(b.f); | |
else if (b.o) { | |
d = b.o.replace(/<a /g, "<span ").replace(/\/a>/g, "/span>"); | |
b.K = !0; | |
delete b.o; | |
b.o = null; | |
b.b = []; | |
e = jg(document, Za); | |
Q(e, !1); | |
e.innerHTML = 0 <= d.indexOf("<i>") ? d : "<b>" + d + "</b>"; | |
document.body.appendChild(e); | |
d = []; | |
var f; | |
for (f = e.firstChild; f; f = f.nextSibling) | |
if ("I" == | |
f.tagName) var h = yt(b, Kg(f), f.innerHTML); | |
else if ("B" == f.tagName) { | |
h || (h = yt(b, "", "")); | |
if (1 == b.a.length) xt(h.$, d, 0, f); | |
else { | |
var k = d; | |
var l = f; | |
var m = b.a; | |
h = h.$; | |
for (var n = [], r, w = l.firstChild; w; w = r) r = w.nextSibling, Ct(w); | |
for (r = l.firstChild; r; r = r.nextSibling) r.attributes && r.attributes.i ? (l = parseInt(r.attributes.i.nodeValue, 10), !isNaN(l) && 0 <= l && l < m.length && (m[l].ee && n[l] ? n[l].T += r.firstChild && 3 == r.firstChild.nodeType ? r.firstChild.nodeValue : Kg(r) : n[l] = xt(h, k, l, r))) : 3 == r.nodeType && h.push({ | |
R: -1, | |
T: De(r.nodeValue) | |
}); | |
null != h && 0 < h.length && -1 == h[0].R && (1 == h.length ? h[0].R = 0 : (h[1].T = h[0].T + h[1].T, h.shift())) | |
} | |
h = void 0 | |
} | |
f = b.b; | |
for (k = 0; k < f.length - 1; ++k) m = f[k], h = ze(m.$[m.$.length - 1].T), h = h.charCodeAt(h.length - 1), 12288 <= h && 12351 >= h || 65280 <= h && 65519 >= h || (m.$[m.$.length - 1].T += " "); | |
sg(e); | |
for (e = 0; e < b.a.length; ++e) e < d.length && e < b.l.length && null != d[e] && (f = b.l[e], k = d[e].start, null != k && (m = f.substring(0, f.length - ye(f).length), " " == m && (m = ""), m && (k.T = m + ye(k.T))), k = d[e].end, null != k && (f = f.substring(ze(f).length), " " == f && (f = ""), f && (k.T = | |
ze(k.T) + f))); | |
1 != b.b.length || b.b[0].lf || (b.b[0].lf = b.f); | |
c.write(b.f, b.b); | |
zt(b) | |
} | |
b.H || (this.W = !1); | |
c = b.g ? !0 : void 0; | |
a.K += b.G; | |
null != c && (a.qa = !0); | |
b = Math.min(Math.floor(100 * a.K / a.f), 100); | |
if (a.o != b || c) a.o = b, a.L ? (a.l(a.o, !0, c), a.W(a.K)) : a.l(a.o, !1, c); | |
return !1 | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once __DIR__ . '/vendor/autoload.php'; | |
use vielhuber\stringhelper\__; | |
use Faker\Factory; | |
class GoogleTranslate | |
{ | |
function translate($string) | |
{ | |
$string = $this->parseResultPre($string); | |
$args = [ | |
'anno' => 3, | |
'client' => 'te_lib', | |
'format' => 'html', | |
'v' => '1.0', | |
'key' => 'AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw', | |
'logld' => 'vTE_20200210_00', | |
'sl' => 'de', | |
'tl' => 'en', | |
'sp' => 'nmt', | |
'tc' => 1, | |
'sr' => 1, | |
'tk' => $this->generateTk($string, $this->generateTkk()), | |
'mode' => 1 | |
]; | |
$response = __::curl( | |
'https://translate.googleapis.com/translate_a/t?' . http_build_query($args), | |
['q' => $string], | |
'POST', | |
[ | |
'User-Agent' => | |
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36', | |
'Content-Length' => strlen('q=' . urlencode($string)) | |
], | |
false, | |
false, | |
3 | |
); | |
return ['result' => $this->parseResultPost($response->result), 'status' => $response->status]; | |
} | |
private function parseResultPre($input) | |
{ | |
// google sometimes surrounds the translation with <i> and <b> tags | |
// do distinguish real i-/b-tags, replace them (we undo that later on) | |
$dom = __::str_to_dom($input); | |
$xpath = new \DOMXPath($dom); | |
foreach (['i', 'b'] as $tags__value) { | |
foreach ($dom->getElementsByTagName($tags__value) as $divs__value) { | |
$divs__value->setAttribute('data-native', 'true'); | |
} | |
} | |
$nodes = $xpath->query('/html/body//*'); | |
if (count($nodes) > 0) { | |
$id = 1; | |
foreach ($nodes as $nodes__value) { | |
$nodes__value->setAttribute('gtid', $id); | |
$id++; | |
} | |
} | |
$output = __::dom_to_str($dom); | |
return $output; | |
} | |
private function parseResultPost($input) | |
{ | |
// sometimes google returns an array | |
if (is_array($input) && !empty($input)) { | |
$input = $input[0]; | |
} | |
// discard the (outer) <i>-tags and take the content of the <b>-tags | |
$output = ''; | |
$pointer = 0; | |
$lvl_i = 0; | |
$lvl_i_inner = 0; | |
$lvl_b = 0; | |
$lvl_b_inner = 0; | |
// multibyte split to array of chars | |
foreach (preg_split('//u', $input, -1, PREG_SPLIT_NO_EMPTY) as $chars__value) { | |
if ($pointer >= 3 && mb_substr($input, $pointer - 3, 3) === '<i>') { | |
$lvl_i_inner++; | |
} | |
if ($pointer >= 3 && mb_substr($input, $pointer - 3, 3) === '<b>') { | |
$lvl_b_inner++; | |
} | |
if (mb_substr($input, $pointer, 4) === '</i>' && $lvl_i_inner > 0) { | |
$lvl_i_inner--; | |
} | |
if (mb_substr($input, $pointer, 4) === '</b>' && $lvl_b_inner > 0) { | |
$lvl_b_inner--; | |
} | |
if (mb_substr($input, $pointer, 3) === '<i>') { | |
$lvl_i++; | |
} | |
if (mb_substr($input, $pointer, 3) === '<b>') { | |
$lvl_b++; | |
} | |
if ($pointer >= 4 && mb_substr($input, $pointer - 4, 4) === '</i>' && $lvl_i > 0) { | |
$lvl_i--; | |
} | |
if ($pointer >= 4 && mb_substr($input, $pointer - 4, 4) === '</b>' && $lvl_b > 0) { | |
$lvl_b--; | |
} | |
$pointer++; | |
// discard multiple spaces | |
if ($chars__value === ' ' && mb_strlen($output) > 0 && mb_substr($output, -1) === ' ') { | |
continue; | |
} | |
// save | |
if (($lvl_b_inner >= 1 && $lvl_i_inner === 0) || ($lvl_b === 0 && $lvl_i === 0)) { | |
$output .= $chars__value; | |
} | |
} | |
$output = trim($output); | |
$dom = __::str_to_dom($output); | |
$xpath = new \DOMXPath($dom); | |
foreach (['i', 'b'] as $tags__value) { | |
foreach ($dom->getElementsByTagName($tags__value) as $divs__value) { | |
$divs__value->removeAttribute('data-native'); | |
} | |
} | |
// merge neighbour elements with the same id together | |
$nodes = $xpath->query('/html/body//*[@gtid]'); | |
if (count($nodes) > 0) { | |
foreach ($nodes as $nodes__value) { | |
if ($nodes__value->hasAttribute('please-remove')) { | |
continue; | |
} | |
$id = $nodes__value->getAttribute('gtid'); | |
$html = $nodes__value->nodeValue; | |
$nextSibling = $nodes__value->nextSibling; | |
if ($nextSibling === null) { | |
continue; | |
} | |
if ($nextSibling->nodeName === '#text' && trim($nextSibling->textContent) == '') { | |
$nextSibling = $nextSibling->nextSibling; | |
} | |
if ($nextSibling === null || $nextSibling->nodeName === '#text') { | |
continue; | |
} | |
$id2 = $nextSibling->getAttribute('gtid'); | |
if ($id !== $id2) { | |
continue; | |
} | |
$nextSibling->setAttribute('please-remove', '1'); | |
$html .= ' ' . $nextSibling->nodeValue; | |
$nodes__value->nodeValue = $html; | |
} | |
foreach ($nodes as $nodes__value) { | |
$nodes__value->removeAttribute('gtid'); | |
if ($nodes__value->hasAttribute('please-remove')) { | |
$nodes__value->parentNode->removeChild($nodes__value); | |
} | |
} | |
} | |
$output = __::dom_to_str($dom); | |
return $output; | |
} | |
private function generateTkk() | |
{ | |
$cache = sys_get_temp_dir() . '/tkk.cache'; | |
if (file_exists($cache) && filemtime($cache) > strtotime('now - 1 hour')) { | |
return file_get_contents($cache); | |
} | |
$data = __::curl('https://translate.googleapis.com/translate_a/element.js', null, 'GET'); | |
$response = $data->result; | |
$pos1 = mb_strpos($response, 'c._ctkk=\'') + mb_strlen('c._ctkk=\''); | |
$pos2 = mb_strpos($response, '\'', $pos1); | |
$tkk = mb_substr($response, $pos1, $pos2 - $pos1); | |
file_put_contents($cache, $tkk); | |
return $tkk; | |
} | |
private function generateTk($f0, $w1) | |
{ | |
// ported from js to php from https://translate.googleapis.com/element/TE_20200210_00/e/js/element/element_main.js | |
$w1 = explode('.', $w1); | |
$n2 = $w1[0]; | |
for ($j3 = [], $t4 = 0, $h5 = 0; $h5 < strlen(mb_convert_encoding($f0, 'UTF-16LE', 'UTF-8')) / 2; $h5++) { | |
$z6 = | |
ord(mb_convert_encoding($f0, 'UTF-16LE', 'UTF-8')[$h5 * 2]) + | |
(ord(mb_convert_encoding($f0, 'UTF-16LE', 'UTF-8')[$h5 * 2 + 1]) << 8); | |
if (128 > $z6) { | |
$j3[$t4++] = $z6; | |
} else { | |
if (2048 > $z6) { | |
$j3[$t4++] = ($z6 >> 6) | 192; | |
} else { | |
if ( | |
55296 == ($z6 & 64512) && | |
$h5 + 1 < strlen(mb_convert_encoding($f0, 'UTF-16LE', 'UTF-8')) / 2 && | |
56320 == | |
((ord(mb_convert_encoding($f0, 'UTF-16LE', 'UTF-8')[($h5 + 1) * 2]) + | |
(ord(mb_convert_encoding($f0, 'UTF-16LE', 'UTF-8')[($h5 + 1) * 2 + 1]) << 8)) & | |
64512) | |
) { | |
$h5++; | |
$z6 = | |
65536 + | |
(($z6 & 1023) << 10) + | |
((ord(mb_convert_encoding($f0, 'UTF-16LE', 'UTF-8')[$h5 * 2]) + | |
(ord(mb_convert_encoding($f0, 'UTF-16LE', 'UTF-8')[$h5 * 2 + 1]) << 8)) & | |
1023); | |
$j3[$t4++] = ($z6 >> 18) | 240; | |
$j3[$t4++] = (($z6 >> 12) & 63) | 128; | |
} else { | |
$j3[$t4++] = ($z6 >> 12) | 224; | |
} | |
$j3[$t4++] = (($z6 >> 6) & 63) | 128; | |
} | |
$j3[$t4++] = ($z6 & 63) | 128; | |
} | |
} | |
$f0 = $n2; | |
for ($t4 = 0; $t4 < count($j3); $t4++) { | |
$f0 += $j3[$t4]; | |
$c7 = $f0; | |
$x8 = '+-a^+6'; | |
for ($r9 = 0; $r9 < strlen($x8) - 2; $r9 += 3) { | |
$u10 = $x8[$r9 + 2]; | |
$u10 = 'a' <= $u10 ? ord($u10[0]) - 87 : intval($u10); | |
$a11 = $c7; | |
$c12 = $u10; | |
if ($c12 >= 32 || $c12 < -32) { | |
$c13 = (int) ($c12 / 32); | |
$c12 = $c12 - $c13 * 32; | |
} | |
if ($c12 < 0) { | |
$c12 = 32 + $c12; | |
} | |
if ($c12 == 0) { | |
return (($a11 >> 1) & 0x7fffffff) * 2 + (($a11 >> $c12) & 1); | |
} | |
if ($a11 < 0) { | |
$a11 = $a11 >> 1; | |
$a11 &= 2147483647; | |
$a11 |= 0x40000000; | |
$a11 = $a11 >> $c12 - 1; | |
} else { | |
$a11 = $a11 >> $c12; | |
} | |
$b14 = $a11; | |
$u10 = '+' == $x8[$r9 + 1] ? $b14 : $c7 << $u10; | |
$c7 = '+' == $x8[$r9] ? ($c7 + $u10) & 4294967295 : $c7 ^ $u10; | |
} | |
$f0 = $c7; | |
} | |
$c7 = $f0; | |
$x8 = '+-3^+b+-f'; | |
for ($r9 = 0; $r9 < strlen($x8) - 2; $r9 += 3) { | |
$u10 = $x8[$r9 + 2]; | |
$u10 = 'a' <= $u10 ? ord($u10[0]) - 87 : intval($u10); | |
$a11 = $c7; | |
$c12 = $u10; | |
if ($c12 >= 32 || $c12 < -32) { | |
$c13 = (int) ($c12 / 32); | |
$c12 = $c12 - $c13 * 32; | |
} | |
if ($c12 < 0) { | |
$c12 = 32 + $c12; | |
} | |
if ($c12 == 0) { | |
return (($a11 >> 1) & 0x7fffffff) * 2 + (($a11 >> $c12) & 1); | |
} | |
if ($a11 < 0) { | |
$a11 = $a11 >> 1; | |
$a11 &= 2147483647; | |
$a11 |= 0x40000000; | |
$a11 = $a11 >> $c12 - 1; | |
} else { | |
$a11 = $a11 >> $c12; | |
} | |
$b14 = $a11; | |
$u10 = '+' == $x8[$r9 + 1] ? $b14 : $c7 << $u10; | |
$c7 = '+' == $x8[$r9] ? ($c7 + $u10) & 4294967295 : $c7 ^ $u10; | |
} | |
$f0 = $c7; | |
$f0 ^= $w1[1] ? $w1[1] + 0 : 0; | |
if (0 > $f0) { | |
$f0 = ($f0 & 2147483647) + 2147483648; | |
} | |
$f0 = fmod($f0, pow(10, 6)); | |
return $f0 . '.' . ($f0 ^ $n2); | |
} | |
} | |
$gt = new GoogleTranslate(); | |
$faker = Factory::create('de_DE'); | |
$chars = 0; | |
for ($i = 0; $i < 1000; $i++) { | |
$orig = $faker->realText(250); | |
$chars += mb_strlen($orig); | |
$response = $gt->translate($orig); | |
logStatus([$response['status'], $chars, $orig, $response['result']]); | |
echo $response['status'] . ': ' . $chars . PHP_EOL; | |
} | |
function logStatus($msg) | |
{ | |
file_put_contents('log.txt', date('Y-m-d H:i:s') . "\t" . implode("\t", $msg) . PHP_EOL, FILE_APPEND); | |
} |
It's working
its not working. are you have any new solution?
its not working,google translate changed
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes, just tested.
I just had to add a small line since google returns sometimes arrays instead of strings:
https://gist.github.com/vielhuber/b7739bf50b2edcf636c43a8f8910def9/revisions#diff-13c8070b20b0c3271f899b6381691ae2604aecb086fb2a01fd7f99f08ff70fbe