Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Работаем с Яндекс-Переводчиком / 24 сообщений из 24, страница 1 из 1
21.03.2018, 12:33
    #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
21.03.2018, 12:41
    #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
21.03.2018, 12:44
    #39618112
asutp2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
уточняю: функцию YandexTranslate нужно перенести в класс
...
Рейтинг: 0 / 0
21.03.2018, 12:47
    #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
21.03.2018, 12:52
    #39618121
asutp2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
Еще раз - перенеси YandexTranslate в класс
...
Рейтинг: 0 / 0
21.03.2018, 12:56
    #39618131
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
asutp2уточняю: функцию YandexTranslate нужно перенести в класс
Не совсем врубаюсь что и как, если не трудно - можете подправить?
Вот ссылка на проект: Yandex_Translate
Буду Вам очень признателен!
...
Сам вижу что у меня получилось два штуки: IdHTTP1 и IdHTTP2
Один из uses IdHTTP, второй - Компонента на форме...(((
...
Рейтинг: 0 / 0
21.03.2018, 13:01
    #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
21.03.2018, 13:10
    #39618145
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
asutp2 , сделал... )) Спасибо!
До этого как-то не приходилось объявлять функции как процедуры..)
...
Все скомпилировалось без ошибок, только получил вот это в ответ:
...
Рейтинг: 0 / 0
21.03.2018, 13:17
    #39618156
asutp2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
Bellic,

здесь уже нужно разбираться с запросом)
...
Рейтинг: 0 / 0
21.03.2018, 13:31
    #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
21.03.2018, 15:36
    #39618317
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
...
Попробовал в строке "result := UTF8ToWideString(OutS.Text);" всяко разно:
- UTF8EncodeToShortString
- UTF8ToString
- UTF8ToWideString
- UTF8ToUnicodeString
- UTF8EncodeToShortString
Результат аналогичен - "??????????????"
...
Рейтинг: 0 / 0
21.03.2018, 16:50
    #39618383
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
Сделайте
Код: pascal
1.
MyMemory.SaveToFile(....)

и посмотрите, что в самом файле
...
Рейтинг: 0 / 0
21.03.2018, 16:53
    #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
21.03.2018, 17:05
    #39618397
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
_Vasilisk_Сделайте
Код: pascal
1.
MyMemory.SaveToFile(....)

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


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


Хренушки..(((
В общем - это два иероглифа, с переводом на Английский - "YES"
...
Что то мне так кажется, что у Яндекса нужно еще попросить другую кодировку при переводе!?
...
Рейтинг: 0 / 0
21.03.2018, 21:36
    #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
21.03.2018, 22:06
    #39618529
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
TIdURI.URLEncode(...)

юнит IdURI
...
Рейтинг: 0 / 0
21.03.2018, 22:09
    #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
21.03.2018, 22:15
    #39618537
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
Vizit0rTIdURI.URLEncode(...)
юнит IdURI
Попробовал самым первым, получил " Protocol field is empty ", не стал искать причину и использовал функцию выше...
А может зря не искал???..)))
...
Рейтинг: 0 / 0
21.03.2018, 22:37
    #39618541
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работаем с Яндекс-Переводчиком
потому что адрес должен быть полным, начинаться с http(s)://
...
Рейтинг: 0 / 0
21.03.2018, 22:50
    #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
21.03.2018, 23:07
    #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
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Работаем с Яндекс-Переводчиком / 24 сообщений из 24, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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