После закрытия Гуглом своих API для перевода проблема поиска онлайн-сервис для машинного перевода стала особенно актуальной.
В Интернете много сервисов перевода с громкими именами: Промт, Прагма и пр. Нет никакой проблемы в PHP смоделировать обращения к страницам сервисов и получить результаты перевода. Но есть проблема: почти все сервисы в ответ на простой GET или POST запрос отдают не результат перевода, а целиком страницу во всей красе, начиная с DTD. Как говорят у нас на Украине, “дурных нэма”.
После анализа было выяснено, что есть только два сервиса, которые отдают в ответ на запрос только результат перевода: Яндекс и Bing от Microsoft.
<a name="habracut">
Забегая значительно вперед, укажем области применения и особенности:
Яндекс проще в использовании, прекрасно переводит с русского и на русский, но тут же и недостаток: Яндекс переводит только с русского или только на русский. Перевести Яндексом с украинского на английский в одну операцию невозможно.
Bing этим не страдает, но зато:
— переводы, в которых участвует русский или украинский, страдают сильным “акцентом” и обязательно требуют правки
— использование Bing в режиме free имеет некоторые ограничения
— для использования Bing требуется некий идентификатор веб-приложения — appID, само по себе получение которого не связано с юридическими трудностями — это фактически просто регистрация, но которая представляет собой увлекательный и длинный квест.
Итак, какие задачи должна решать библиотека/класс для перевода?
1. Получение языков, с которых и на которые можно переводить, и их допустимых комбинаций
2. Собственно сам перевод текста
Сразу ремарка. Из соображений здравого смысла ясно, что в один заход перевести “Войну и мир” не получится. Приземление на технический уровень дает более четкое ограничение: переводчик Янекса использует GET-запросы, соотв. — очень грубо — примерно 2000 символов за один раз, не более. Это совсем немного, примерно 2 небольших абзаца текста, даже небольшая публикация на сайте выйдет за эти рамки.
Отсюда следующая задача:
3. Перевод больших фрагментов текста.
Ну и представим задачу: мультиязычный сайт. Гонять каждый раз переводчик за переводом элементов интерфейса и прочих текстов на сайте — это, мягко говоря, неразумно. Соответственно задача:
4. Кеширование.
Кеширование нужно еще для одной цели: переводчик от Яндекса хорош, но не идеален, особенно с учетом богатства русского языка. Зачастую хотелось бы поправить результат перевода, а для этого нужно его где-то хранить.
Итак, Яндекс.Переводчик
Исходники доступны в репозитории Гугла и задокументированы на русском языке.
1) Языки перевода.
Класс Yandex_Translate содержит три метода с говорящими названиями:
yandexGetLangsPairs() — получение доступных пар языков FROM->TO
yandexGet_FROM_Langs()
yandexGet_TO_Langs()
Пример (этот пример — полный, ниже подключение файлов, создание экземпляра класса, элементы форматирования вывода и пр. буду опущены.)
<?php
include_once 'Yandex_Translate.php';
$pairs = $translator->yandexGetLangsPairs();
print_r($pairs);
Получим вот такие комбинации (они, кстати, меняются время от времени):
[0] => en-ru
[1] => ru-en
[2] => ru-uk
[3] => uk-ru
[4] => pl-ru
[5] => ru-pl
[6] => tr-ru
[7] => ru-tr
[8] => de-ru
[9] => ru-de
[10] => fr-ru
[11] => ru-fr
[12] => it-ru
[13] => es-ru
[14] => ru-es
Обратите внимание, что во всех парах есть язык ru, ну об этом выше уже говорилось.
Два других метода дают языки по отдельности и могут быть использованы, например, для формирования селектов или других элементов выбора.
2. Перевод
Один метод, три аргумента: с какого, на какой и собственно переводимый текст.
Обратите внимание также на важное свойство eolSymbol — окончание строки. Если его установить неверно, не будет форматирования выходного текста (см. комментарии в исходниках).
Пример:
$text = file_get_contents('text.txt');
$translatedText = $translator->yandexTranslate('ru', 'uk', $text);
echo $translatedText;
Начало файла text.txt:
Марио Пьюзо Крестный отец
Посвящается Энтони Клири
КНИГА ПЕРВАЯ
За всяким большим состоянием кроется преступление.
Результат выполнения скрипта:
Маріо п’юзо Хрещений батько
Присвячується Ентоні Клірі
ПЕРША КНИГА
За кожним великим станом криється злочин.
Сразу обратим внимание — перевод хороший, но правка требуется.
3. Перевод больших текстов
Для перевода больших текстов служит абстрактный класс Big_Text_Translate
Принцип следующий.
Сначала текст разбивается на предложения, используя разделитель sentensesDelimiter — по умолчанию точка.
Правильнее конечно было бы использовать точку с пробелом, но в реальных, например, “каментах” пробел после точки запросто может “ацуцтвовать”. Поэтому так, проблем в реальной работе это не вызывает, но свойство можно переопределить.
Затем предложения собираются в текстовые фрагменты, размер которых не превышает заданного значения symbolLimit — по умолчанию 2000.
Текстовые фрагменты готовы для перевода, семантика и форматирование — сохранены. Формированием фрагментов занимается статический метод toBigPieces, на выходе — массив.
Метод fromBigPieces склеивает переведенные фрагменты обратно в цельный текст.
Пример
$bigText = file_get_contents('text_big.txt');
$textArray = Big_Text_Translate::toBigPieces($bigText);
$numberOfTextItems = count($textArray);
foreach ($textArray as $key=>$textItem){
//Показываем прогресс перевода
echo 'Переведен фрагмент '.$key.' из '.$numberOfTextItems;
flush();
$translatedItem = $translator->yandexTranslate('ru', 'uk', $textItem);
$translatedArray[$key] = $translatedItem;
}
$translatedBigText = Big_Text_Translate::fromBigPieces($translatedArray);
echo $translatedBigText;
Выполнение примера пробуйте сами — все есть в репозитории.
Уважаемые читатели! Если материал представляет интерес, то готовится его продолжение, включающее разделы:
— кеширование результатов перевода в несколько уровней
— работа с сервисом Bing
— полноценное демо: построение мультиязычного сайта.
Автор: konst20