powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Работаем с Яндекс-Переводчиком
24 сообщений из 24, страница 1 из 1
Работаем с Яндекс-Переводчиком
    #39618103
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго всем времени суток!
Пытаюсь победить Яндекс-Переводчик, точнее - заставить программу работать с этим Сервисом...
Видимо не я первый занимаюсь этой темой, но как ни странно - инфы в Инете мало...
...
Программа очень проста - два ТEdit и Батон, одна функция и процедура:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdHTTP, IdTCPConnection,
  IdTCPClient, IdBaseComponent, IdComponent, IdIOHandler, IdIOHandlerSocket,
  IdIOHandlerStack, IdSSL, IdSSLOpenSSL;

type
  TForm1 = class(TForm)
    JapanTextEdit: TEdit;
    TranslateTextEdit: TEdit;
    TranslateButton: TButton;
    IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
    IdHTTP1: TIdHTTP;
    procedure YandexTrans(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function YandexTranslate(FromLng, ToLng, Text: String { out SrcLng: String } ): string;
var
  InData: TStringList;
  Translate: String;
  IdHTTP2: TIdHTTP;
  Key: string;
begin
     Key := '... яндексовский ключик ...';
     Result := '';
     IdHTTP2 := TIdHTTP.Create(nil);
     IdHTTP2.Request.UserAgent := 'Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.16';
     InData := TStringList.Create;

     //XML-интерфейс
     InData.Add('?key=' + Key);
     InData.Add('&text=' + Text);
     InData.Add('&lang=' + FromLng + '-' + ToLng);

     try
          //XML-интерфейс
          Translate := IdHTTP2.Post('https://translate.yandex.net/api/v1.5/tr/translate', InData);
          try
               Result := Translate;
          except
               on E: Exception do
               ShowMessage(E.ClassName + ' error raised, with message : ' + E.Message);
          end;
     finally
          InData.Free;
          IdHTTP2.Free; // IdHTTP1.Disconnect;
     end;
end;

procedure TForm1.YandexTrans(Sender: TObject);
begin
     JapanTextEdit.Text := 'グループ迂回メモリを全て消去しました'; // Тут японская фраза. Если не видно - выложу позже.
     TranslateTextEdit.Text := YandexTranslate('ja', 'en', JapanTextEdit.Text);
     TranslateTextEdit.Text := StringReplace(TranslateTextEdit.Text,'"','',[rfReplaceAll]);
end;

end.


Дополнительно:
- на форме присутствует компонент IdHTTP1 и IdSSLIOHandlerSocketOpenSSL1 ;
- в каталоге с исполняемым файлом лежат libeay32.dll , ssleay32.dll ;
- в свойстве IOHandler компонента IdHTTP1 указан IdSSLIOHandlerSocketOpenSSL1 ;
- Yandex-Key упущен по понятным причинам.
- Делфи XE3.

Все вроде сделал как велит Яндекс и подсказывают скудные материалы Инета, но получаю в ответ:
" IOHandler value is not valid "

Помогите пожалуйста разобраться, кто в теме?!
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618109
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

в коде для запроса используется IdHTTP2, поэтому после
Код: pascal
1.
2.
IdHTTP2 := TIdHTTP.Create(nil);
IdHTTP2.Request.UserAgent := 'Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.16';


нужно добавить
Код: pascal
1.
IdHTTP2.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618112
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
уточняю: функцию YandexTranslate нужно перенести в класс
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618117
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
asutp2Bellic,

в коде для запроса используется IdHTTP2, поэтому после
Код: pascal
1.
2.
IdHTTP2 := TIdHTTP.Create(nil);
IdHTTP2.Request.UserAgent := 'Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.16';


нужно добавить
Код: pascal
1.
IdHTTP2.IOHandler := IdSSLIOHandlerSocketOpenSSL1;


Добавил, но теперь ругается, что не ведает о IdSSLIOHandlerSocketOpenSSL1 , хотя он вроде объявлен выше:
Код: pascal
1.
IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618121
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще раз - перенеси YandexTranslate в класс
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618131
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
asutp2уточняю: функцию YandexTranslate нужно перенести в класс
Не совсем врубаюсь что и как, если не трудно - можете подправить?
Вот ссылка на проект: Yandex_Translate
Буду Вам очень признателен!
...
Сам вижу что у меня получилось два штуки: IdHTTP1 и IdHTTP2
Один из uses IdHTTP, второй - Компонента на форме...(((
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618135
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

1. следующей строкой после
Код: pascal
1.
procedure YandexTrans(Sender: TObject);

нужно добавить новую строку
Код: pascal
1.
function YandexTranslate(FromLng, ToLng, Text: String { out SrcLng: String } ): string;


2. ниже, в уже существующей строке
Код: pascal
1.
function YandexTranslate(FromLng, ToLng, Text: String { out SrcLng: String } ): string;

нужно изменить на
Код: pascal
1.
function TForm1.YandexTranslate(FromLng, ToLng, Text: String { out SrcLng: String } ): string;
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618145
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
asutp2 , сделал... )) Спасибо!
До этого как-то не приходилось объявлять функции как процедуры..)
...
Все скомпилировалось без ошибок, только получил вот это в ответ:
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618156
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bellic,

здесь уже нужно разбираться с запросом)
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618174
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
asutp2Bellic,
здесь уже нужно разбираться с запросом)

Вот нашел еще немного другую реализацию Функции-Перевода:
(Ее кстати не надо добавлять в Класс, как предыдущую!)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
function TranslateText(FromLng, ToLng, Text: string): string;
var
  IdHTTP: TIdHttp;
  SSL: TIdSSLIOHandlerSocketOpenSSL;
  MyMemory: TMemoryStream;
  OutS: TStringList;
  s: string;
  Key, Lang: string;
begin
     Key := 'trnsl.****';
     Lang := FromLng + '-' + ToLng;
     IdHTTP := TIdHTTP.Create;
     SSL := TIdSSLIOHandlerSocketOpenSSL.Create;
     IdHTTP.IOHandler := SSL;
     s := 'https://translate.yandex.net/api/v1.5/tr/translate?key=' + key + '&lang=' + lang + '&text=' + Text;
     MyMemory := TMemoryStream.Create;
     {if IdHTTP.Connected=true then
          IdHTTP.Get(s, MyMemory);
     try
          idSMTP1.Disconnect;
     except

     end; }

     IdHTTP.Get(s, MyMemory);
     //IdHTTP.Disconnect;
     {
     try
          IdHTTP.Get(s, MyMemory);
          IdHTTP.Disconnect;
     except
          on E : Exception do
               if E is EIdConnClosedGracefully then
                    raise
     end  }

     MyMemory.Position := 0;
     OutS := TStringList.Create;
     OutS.LoadFromStream(MyMemory);
     result := UTF8ToWideString(OutS.Text);
     //result := OutS.Text;
     IdHTTP.Free;
     IdHTTP.Disconnect;
     SSL.Free;
     //SSL.DiscardAll;
     MyMemory.Free;
     OutS.Free;
end;

Достаточно только заменить строку вызова:
Код: pascal
1.
2.
//TranslateTextEdit.Text := YandexTranslate('ja', 'en', JapanTextEdit.Text);
     TranslateTextEdit.Text := TranslateText('ja', 'en', JapanTextEdit.Text);


В ответ выдает в XML-формате:
Код: xml
1.
2.
<?xml version=1.0 encoding=utf-8?>
<Translation code=200 lang=ja-en><text>??????????????????</text></Translation>


(code 200 - это ответ сервера "Операция выполнена успешно")

Вместо символов "??????????????????" должен быть текст на Английском языке, но его нету!..((
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618317
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Попробовал в строке "result := UTF8ToWideString(OutS.Text);" всяко разно:
- UTF8EncodeToShortString
- UTF8ToString
- UTF8ToWideString
- UTF8ToUnicodeString
- UTF8EncodeToShortString
Результат аналогичен - "??????????????"
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618383
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделайте
Код: pascal
1.
MyMemory.SaveToFile(....)

и посмотрите, что в самом файле
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618385
terlalex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня нормально работает

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
function translate(g:string):string ;
  var
   Data: TStringList;
    s5 , s1, s2, s3 : String;
begin
Data := TStringList.Create;
try

   s1 := StringReplace(g,#13#10, '.',  [rfReplaceAll, rfIgnoreCase]) ;
   s2 := ComboBox5.Text ;
   delete(s2,1,pos(' ',s2));
   s3 := ComboBox6.Text ;
   delete(s3,1,pos(' ',s3));
   Data.Text :=  'text=' + s1 ;

try

 s5 :=  form1.IdHTTP1.Post('https://translate.yandex.net/api/v1.5/tr.json/translate?lang=' + s2 + '-' + s3 + '&key=trnsl.1.1.***', Data) ;

except
on E: Exception do
ShowMessage(E.ClassName + ' error raised, with message : ' + E.Message);
end;
  translate := Copy(s5,Pos('["',s5)+2,Pos('"]',s5)-Pos('["',s5)-2) else
  translate   :=   g ;

finally
Data.Free;



ComboBox5 и ComboBox6 - языки

Модератор: Пользуйтесь тегом (кнопкой) SRC для оформления кода, пожалуйста.
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618397
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_Сделайте
Код: pascal
1.
MyMemory.SaveToFile(....)

и посмотрите, что в самом файле
Все то же самое и в файле!
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618402
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
terlalex , к сожалению я с JSON пока не знаком, из XML думаю выудить перевод будет гораздо проще..
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618408
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Впрочем - подправив строку запроса, получил и JSON:
Код: javascript
1.
{"code":200,"lang":"ja-en","text":["????????"]}


...
А тут то возможно и проще распарсить будя!..))
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618427
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изменил японскую фразу на по-короче(Отобразится ли тут?):
Код: sql
1.
&#12399;&#12356;


Хренушки..(((
В общем - это два иероглифа, с переводом на Английский - "YES"
...
Что то мне так кажется, что у Яндекса нужно еще попросить другую кодировку при переводе!?
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618516
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем так:
- для функции (методом GET)
Код: pascal
1.
TranslateText('ja', 'en', JapanTextEdit.Text);


проблема наличия в ответе "???????" (восклицательных знаков) найдена... в моей невнимательности..))
Перечитал еще раз описание ( https://tech.yandex.ru/translate/doc/dg/reference/translate-docpage/), а именно примечание:
автор"Для исходного текста обязательно используйте URL-кодирование"
Далее, сходил на первый попавшийся сервис( http://xinit.ru/web_tools/##urlencode) и подсунув японские иероглифы "はい", получил строку:
Код: pascal
1.
%E3%81%AF%E3%81%84

, которую и передал серверу.
В результате - правильный, ожидаемый перевод - " Yes "

Осталось найти как выполнить URL-преобразование в Delphi...

- для функции (методом Pos SSL)
Код: pascal
1.
YandexTranslate('ja', 'en', JapanTextEdit.Text);


Пока все на том же месте... - 400 Bad Request
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618529
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TIdURI.URLEncode(...)

юнит IdURI
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618531
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По теме "URL-кодирование" пригодилась следующая функция:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
//==============================================================================
function UrlEncode(Str: ansistring): ansistring;
  function CharToHex(Ch: ansiChar): Integer;
  asm
          and eax, 0FFh
          mov ah, al
          shr al, 4
          and ah, 00fh
          cmp al, 00ah
          jl @@10
          sub al, 00ah
          add al, 041h
          jmp @@20
     @@10:
          add al, 030h
     @@20:
          cmp ah, 00ah
          jl @@30
          sub ah, 00ah
          add ah, 041h
          jmp @@40
     @@30:
          add ah, 030h
     @@40:
          shl eax, 8
          mov al, '%'
  end;

var
  i, Len: Integer;
  Ch: ansiChar;
  N: Integer;
  P: PansiChar;
begin
     Result := '';
     Len := Length(Str);
     P := PansiChar(@N);
     for i := 1 to Len do
          begin
               Ch := Str[i];
               if Ch in ['0'..'9', 'A'..'Z', 'a'..'z', '_'] then
                    Result := Result + Ch
               else
                    begin
                         if Ch = ' ' then
                              Result := Result + '+'
                         else
                              begin
                                   N := CharToHex(Ch);
                                   Result := Result + P;
                              end;
                    end;
          end;
end;
//==============================================================================

(Источник: Кодирование и декодирование кириллицы в Delphi для URL (URLDecode, URLEncode) )

Применение:
Код: pascal
1.
2.
3.
4.
var 
S: string;
S := UrlEncode(AnsiToUtf8(JapanTextEdit.Text));
TranslateTextEdit.Text := TranslateText('ja', 'en', S);


А теперь можно расслабиться, выбрать XML- или JSON-вариант запроса и думкать - как проще распарсить из Оных полученный перевод..))
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618537
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vizit0rTIdURI.URLEncode(...)
юнит IdURI
Попробовал самым первым, получил " Protocol field is empty ", не стал искать причину и использовал функцию выше...
А может зря не искал???..)))
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618541
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
потому что адрес должен быть полным, начинаться с http(s)://
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618546
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vizit0rпотому что адрес должен быть полным, начинаться с http(s)://
Ты имеешь ввиду, что следующую строчку
Код: pascal
1.
s := 'https://translate.yandex.net/api/v1.5/tr.json/translate?key=' + key + '&lang=' + lang + '&text=' + Text;


нужно было ВСЮ пропустить через
Код: pascal
1.
2.
3.
uses IdURI;
т.е. 
TIdURI.URLEncode(s)

???

Могу попробовать..)
...
Рейтинг: 0 / 0
Работаем с Яндекс-Переводчиком
    #39618555
Bellic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vizit0rпотому что адрес должен быть полным, начинаться с http(s)://
Попробовал как сказал выше - тоже все получилось Ок!
Спасибо!
Ну а для парсинга из JSON - удачно подсказал terlalex :
Код: pascal
1.
TranslateTextEdit.Text := Copy(TR, Pos('["', TR) + 2, Pos('"]', TR) - Pos('["',TR)-2);

где TR - ответ, полученный от Сервера в формате JSON...

P.S. Осталась самая "малость" - это боевое крещение в битве с Яндекс-сервером, на последовательных запросах, по своему числу стремящихся к бесконечности!...)))
Но это уже Завтра!
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Работаем с Яндекс-Переводчиком
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]