Since DeepL updated their API which also their website (https://www.deepl.com/translator) uses, an error appears when you're requesting a translation via Java or Python. It says "Too many requests." A year ago the answer here (Using DeepL API to translate text) from EmilioK worked.
Because of their update, the API URL changed to "https://www2.deepl.com/jsonrpc". But the response is {"jsonrpc": "2.0","error":{"code":1042901,"message":"Too many requests."}}
. Translating via the website works, so they seem to have implemented a background check. I already tried to debug their JavaScript code, but I don't understand what I'm doing wrong. At last I tried to re-build the requests by analysing the network traffic from the homepage. Didn't work either.
Besides, it seems like others are having the same problem (https://github.com/EmilioK97/pydeepl/issues/12, https://github.com/vsetka/deepl-translator/issues/9).
I used Java 8 with the Apache HttpClient 4.5.8:
private static final String BASE_URL = "https://www2.deepl.com/jsonrpc";
private static AtomicInteger requestId = new AtomicInteger(10000 * (int) Math.round(10000 * Math.random()));
private static final CloseableHttpClient HTTP_CLIENT = HttpClients.createDefault();
public void example() {
HttpResponse httpResponse = HTTP_CLIENT.execute(generateRequest("Hello", "EN", "DE"), getContext());
JSONObject response = new JSONObject(EntityUtils.toString(httpResponse.getEntity()));
System.out.println(response.toString());
}
HttpContext getContext() {
CookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("LMTBID", "3389513b-e369-4810-a2f3-73b9405e0b0d|403992a1240e1eca6c6e98b428849a3c");
cookie.setDomain(".deepl.com");
cookie.setPath("/");
cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "true");
cookieStore.addCookie(cookie);
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
return localContext;
}
HttpPost generateRequest(String text, String from, String to) {
HttpPost request = new HttpPost(BASE_URL);
StringEntity params = new StringEntity(getJsonRequest(text, from, to).toString(), StandardCharsets.UTF_8);
request.addHeader(HttpHeaders.HOST, "www2.deepl.com");
request.addHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0");
request.addHeader(HttpHeaders.ACCEPT, "*/*");
request.addHeader(HttpHeaders.ACCEPT_LANGUAGE, "de,en-US;q=0.7,en;q=0.3");
request.addHeader(HttpHeaders.ACCEPT_ENCODING, "gzip, deflate, br");
request.addHeader(HttpHeaders.REFERER, "https://www.deepl.com/translator");
request.addHeader(HttpHeaders.CONTENT_TYPE, "text/plain");
request.addHeader(HttpHeaders.CONNECTION, "keep-alive");
request.addHeader("X-Requested-With", "XMLHttpRequest");
request.addHeader("Origin", "https://www.deepl.com");
request.addHeader("DNT", "1");
request.addHeader("TE", "Trailers");
request.setEntity(params);
request.setConfig(requestConfig);
return request;
}
private static JSONObject getJsonRequest(String text, String from, String to) {
JSONObject send = new JSONObject();
send.put("id", requestId.incrementAndGet());
send.put("jsonrpc", "2.0");
send.put("method", "LMT_handle_jobs");
JSONObject paramsObject = new JSONObject();
JSONArray jobsArray = new JSONArray();
JSONObject jobsObject = new JSONObject();
jobsObject.put("kind", "default");
jobsObject.put("quality", "fast");
jobsObject.put("raw_en_context_after", new JSONArray());
jobsObject.put("raw_en_context_before", new JSONArray());
jobsObject.put("raw_en_sentence", text);
jobsArray.put(jobsObject);
JSONObject langObject = new JSONObject();
JSONArray userPreferredLangsArray = new JSONArray();
userPreferredLangsArray.put(to);
userPreferredLangsArray.put(from);
langObject.put("source_lang_user_selected", from.getLanguageCode());
langObject.put("target_lang", to);
langObject.put("user_preferred_langs", userPreferredLangsArray);
paramsObject.put("jobs", jobsArray);
paramsObject.put("lang", langObject);
paramsObject.put("priority", -1);
paramsObject.put("timestamp", System.currentTimeMillis());
send.put("params", paramsObject);
return send;
}
The result should look like this, but I don't remember exactly:
{"result":{"source_lang":"EN","target_lang":"DE","translations":[{"beams":[{"postprocessed_sentence":"Hallo","score":0.5,"totalLogProb":0.3,"num_symbols":1},{"postprocessed_sentence":"Guten Tag","score":0.3,"totalLogProb":0.7,"num_symbols":2}]}]}}