Google oferuje Google Translation API ze strukturą kosztów opartą na użytkowaniu w ramach Google Cloud. Istnieje również nieudokumentowane API, którego można używać bez klucza , ale które odmawia działania po zaledwie kilku żądaniach. Korzystając z funkcji tłumaczenia stron internetowych w Google Chrome, można zauważyć, że strony mogą być tłumaczone w bardzo dobrej jakości bez zauważalnych ograniczeń.
Najwyraźniej zaawansowany model nmt jest już tutaj używany. Ale jakiego interfejsu API używa wewnętrznie przeglądarka Google Chrome do tłumaczenia treści i czy można uzyskać do niego bezpośredni dostęp – nawet po stronie serwera? Do analizy ruchu sieciowego polecamy narzędzia takie jak Wireshark lub Telerik Fiddler , które potrafią również analizować ruch zaszyfrowany. Ale Chrome nawet bezpłatnie wysyła żądania, które wysyła podczas tłumaczenia stron: można je łatwo przeglądać za pomocą narzędzi Chrome DevTools:

Jeśli wykonujesz tłumaczenie, następnie przechwyć kluczowe żądanie POST do https://translate.googleapis.com za pomocą „Kopiuj> Kopiuj jako cURL (bash)” i wykonaj je w narzędziu takim jak np. Postman , możesz bez problemu ponownie wysłać żądanie:

Znaczenie parametrów adresu URL jest również w większości oczywiste.:
| Klucz | Przykładowa wartość | Znaczenie |
| anno | 3 | Tryb adnotacji (wpływa na format zwrotu) |
| klient | te_lib | Informacje o kliencie (zmienne; w interfejsie internetowym Google Tłumacz wartość to „webapp”; ma wpływ na format zwrotu i ograniczenie szybkości) |
| format | html | Format ciągu (ważny przy tłumaczeniu tagów HTML) |
| v | 1.0 | Numer wersji Tłumacza Google |
| klucz | AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw | Klucz API (patrz poniżej) |
| logld | vTE_20200210_00 | Wersja protokołu |
| sl | de | Język źródłowy |
| tl | en | Język docelowy |
| sp | nmt | Model ML |
| tc | 1 | nieznany |
| sr | 1 | nieznany |
| tk | 709408.812158 | Token (patrz poniżej) |
| Moda | 1 | nieznany |
Niektóre nagłówki żądań również są ustawione - ale najczęściej można je zignorować. Po ręcznym odznaczeniu wszystkich nagłówków, w tym tych pochodzących z klienta użytkownika , podczas wprowadzania znaków specjalnych (tutaj podczas tłumaczenia „ Hello World ”) zostaje wykryty problem z kodowaniem:

Jeśli ponownie aktywujesz klienta użytkownika (to zazwyczaj nie powoduje żadnej szkody), API dostarcza zakodowane znaki UTF-8:

Czy osiągnęliśmy już nasz cel i mamy wszystkie informacje, aby korzystać z tego API poza Google Chrome? Jeśli jednak zmienisz ciąg do przetłumaczenia (pole danych q żądania POST) na przykład z „Hello World” na „Hello World ! ”, pojawi się komunikat o błędzie.:

Teraz wykonujemy kolejne tłumaczenie tego zmodyfikowanego ciągu znaków w przeglądarce Google Chrome, korzystając z funkcji tłumaczenia witryny, i odkrywamy, że oprócz parametru q , zmianie uległ także parametr tk (wszystkie pozostałe parametry pozostały takie same).:

Oczywiście jest to token zależny od łańcucha, którego strukturę nie jest łatwo dostrzec. Po uruchomieniu tłumaczenia strony ładowane są następujące pliki:
- 1 plik CSS: translateelement.css
- 4 grafiki: translate_24dp.png (2x), gen204 (2x)
- 2 pliki JS: main_de.js, element_main.js
Te dwa pliki JavaScript są zaciemnione i zminimalizowane. Narzędzia takie jak JS Nice i de4js pomagają nam teraz uczynić te pliki bardziej czytelnymi. Aby zdebugować je na żywo, zalecamy rozszerzenie Chrome Requestly, które tuneluje zdalne pliki lokalnie w locie:

Teraz możemy debugować kod (najpierw CORS musi być aktywowany na serwerze lokalnym). Wydaje się, że odpowiednia sekcja kodu do generowania tokenu jest ukryta w pliku element_main.js w tej sekcji:
b7739bf50b2edcf636c43a8f8910def9
Tutaj tekst jest haszowany za pomocą kilku przesunięć . Ale niestety wciąż brakuje nam jednego elementu układanki: oprócz argumentu a (który jest tekstem do przetłumaczenia), do funkcji Bp () jest przekazywany kolejny argument b - rodzaj ziarna, które wydaje się zmieniać od czasu do czasu i obejmuje również wpada do haszowania. Ale skąd on pochodzi? Jeśli przejdziemy do wywołania funkcji Bp () , znajdziemy następującą sekcję kodu:
b7739bf50b2edcf636c43a8f8910def9
Funkcja Hq jest wcześniej zadeklarowana w następujący sposób:
b7739bf50b2edcf636c43a8f8910def9
Osoba usuwająca zaciemnienia zostawiła tutaj trochę śmieci; po zastąpieniu String.fromCharCode('...') odpowiednimi ciągami znaków, usunięciu przestarzałego a() i połączeniu wywołań funkcji [c(), c()] , otrzymamy:
b7739bf50b2edcf636c43a8f8910def9
Albo jeszcze łatwiej:
b7739bf50b2edcf636c43a8f8910def9
Funkcja yq została wcześniej zdefiniowana jako:
b7739bf50b2edcf636c43a8f8910def9
Zatem ziarno wydaje się znajdować w obiekcie globalnym google.translate._const._ctkk , który jest dostępny w czasie wykonywania. Ale gdzie jest umieszczony? Przynajmniej jest on dostępny także na początku w innym, wcześniej załadowanym pliku JS main_de.js . Na początku dodajemy co następuje:
b7739bf50b2edcf636c43a8f8910def9
W konsoli faktycznie otrzymujemy aktualne ziarno:

To pozostawia Google Chrome, który najwyraźniej zapewnia ziarno jako ostatnią opcję. Na szczęście jego kod źródłowy (Chromium, w tym komponent Tłumacz) jest open source i dlatego jest publicznie dostępny. Pobieramy repozytorium lokalnie i znajdujemy wywołanie funkcji TranslateScript :: GetTranslateScriptURL w pliku translate_script.cc w folderze Components / translate / core / browser:
b7739bf50b2edcf636c43a8f8910def9
Zmienna z adresem URL jest trwale zdefiniowana w tym samym pliku:
b7739bf50b2edcf636c43a8f8910def9
Jeśli teraz bliżej przyjrzymy się plikowi element.js (po dalszym rozjaśnieniu), znajdziemy twardy wpis c._ctkk - obiekt google.translate również zostanie odpowiednio ustawiony i uruchomione zostanie ładowanie wszystkich odpowiednich zasobów (które już wcześniej odkryliśmy):
b7739bf50b2edcf636c43a8f8910def9
Teraz do rozważenia pozostaje klucz parametru (z wartością AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw). Wygląda na to, że jest to ogólny klucz API przeglądarki (który można również znaleźć w niektórych wynikach Google ). Jest ustawiony w Chromium w pliku translate_url_util.cc w folderze Components / translate / core / browser:
b7739bf50b2edcf636c43a8f8910def9
Klucz jest generowany w google_apis / google_api_keys.cc z fikcyjnej wartości:
b7739bf50b2edcf636c43a8f8910def9
Jednak testy pokazują, że wywołania API działają równie dobrze bez tego kluczowego parametru. Eksperymentowanie z API zwraca teraz kod statusu 200 w przypadku pomyślnych wywołań. Po osiągnięciu limitu zwracany jest kod statusu 411 z komunikatem „ Żądania POST wymagają nagłówka o długości zawartości ”. Dlatego zaleca się również dołączenie tego nagłówka (który jest automatycznie ustawiany jako nagłówek tymczasowy w programie Postman).
Format zwracanych przetłumaczonych ciągów jest nietypowy, gdy w jednym żądaniu jest kilka zdań. Poszczególne zdania są otoczone znacznikami i- / b-HTML:

Ponadto Google Chrome nie wysyła pełnego kodu HTML do interfejsu API, ale zapisuje w żądaniu wartości atrybutów, takie jak href (zamiast tego ustawia indeksy, aby tagi można było później przypisać po stronie klienta):

Jeśli zmienisz wartość klienta klucza POST z te_lib (Google Chrome) na webapp ( strony pomocną ), można uzyskać ostateczną tłumaczone ciąg:

Problem polega na tym, że istnieje większe prawdopodobieństwo, że napotkasz ograniczenie szybkości niż przez te_lib (dla porównania: w przypadku aplikacji webowej jest to osiągane po 40 000 znaków, w przypadku te_lib nie ma ograniczenia szybkości). Musimy więc przyjrzeć się bliżej, jak Chrome analizuje wynik. Znajdziemy go tutaj w element_main.js:
b7739bf50b2edcf636c43a8f8910def9
Jeśli wyślesz cały kod HTML do interfejsu API, atrybuty zostaną pozostawione w przetłumaczonej odpowiedzi. Dlatego nie musimy imitować całego zachowania parsowania, a jedynie wyodrębnić końcowy, przetłumaczony ciąg z odpowiedzi. Aby to zrobić, tworzymy mały parser tagów HTML, który odrzuca najbardziej zewnętrzne tagi <i> wraz z ich zawartością i usuwa najbardziej zewnętrzne tagi <b>. Dzięki tej wiedzy (po zainstalowaniu zależności z kompozytorem wymagają fzaninotto / faker vielhuber / stringhelper ) możemy teraz zbudować wersję API tłumaczenia po stronie serwera:
b7739bf50b2edcf636c43a8f8910def9
Poniżej znajdują się wyniki wstępnego testu, który został przeprowadzony na pięciu różnych systemach o różnych przepustowościach i adresach IP:
| Postać | Znaki na żądanie | Trwanie | Wskaźnik błędów | Koszt za pośrednictwem oficjalnego interfejsu API |
| 13.064.662 | ~250 | 03:36:17 | 0% | 237,78 € |
| 24.530.510 | ~250 | 11:09:13 | 0% | 446,46 € |
| 49.060.211 | ~250 | 20:39:10 | 0% | 892,90 € |
| 99.074.487 | ~1000 | 61:24:37 | 0% | 1803,16 € |
| 99.072.896 | ~1000 | 62:22:20 | 0% | 1803,13 € |
| Σ284,802,766 | ~ Ø550 | Σ 159: 11: 37h | 0% | 5183,41 € |
Uwaga: ten wpis na blogu zawierający wszystkie skrypty został napisany wyłącznie do celów testowych. Nie stosować skrypty do użytku produkcyjnego, zamiast pracować z oficjalnego API pomocna .