Переводим книги с помощью Яндекс.API

в 13:13, , рубрики: php, книги, переводчик, переводы, метки: , ,

Зачем это надо

Однажды мне пришло в голову прочитать одну книгу на родном языке автора, английском. После прочтения нескольких страниц стало понятно, что читать придется долго, так как за каждым незнакомым словом приходилось тянуться за словарем, искать нужную страницу, ломать глаза о множество других слов, похожих на искомое… Да еще и таскать с собой лишних полтысячи страниц. Вот и вздумалось собрать небольшой словарик, именно под эту книгу, в который можно было бы заглянуть в любой ситуации — даже когда нет доступа в Интернет.

Что из этого получится

На выходе мы получим самый обычный .txt — файл, в котором на каждой строчке по алфавиту будут размещены редкие слова из книги и их перевод. Такой словарик можно легко встроить, например, в MIDlet для мобильного телефона, или же непосредственно на сайт.

Почему именно Яндекс.API

В Яндексе все просто: отправил слово — пришел перевод. Не надо регистрировать уникальный ключ, как на Google.translate, да и на большое количество запросов он не жалуется.

Реализация

Для осуществления такой затеи будут созданы следующие файлы:

  • handler.php — скрипт, который будет делать всю черную работу
  • index.html — служит для отображения состояния перевода, а также для управления самим процессом
  • stop.php — скрипт, который остановит выполнение handler.php
handler.php

<?php
set_time_limit(0);     # Убираем ограничение на время исполнения скрипта

ignore_user_abort();     # Игнорируем сигнал о завершении от браузера клиента

fopen('flag','x');     # Создаем файл, который будет служить выключателем даного скрипта

@unlink('translated.txt');     # Удаляем старый файл словаря, если существует

$text = file_get_contents('martin_eden.txt');     # Переносим текст из книги (martin_eden.txt) в переменную

$symbols = array('!',',','.',''','"','-',':',';','?',"r",'(',')');
$text = str_replace($symbols, '', $text);     # Удаляем из текста ненужные символы

$text = str_replace("n", ' ', $text);    # Заменяем переносы строк на пробелы

$text_array = explode(' ',$text);    # 'Разрезаем' текст на слова

foreach($text_array as $val){     # Переберем слова и исключим дубликаты
	if($val==''){continue;}
	$val = strtolower($val);
	if(array_key_exists($val, $words)){     # Если такое слово уже есть в массиве, увеличим счетчик
		$words[$val]++;
	}else{     # Если нет - создадим
		$words[$val] = 1;
	}
}

ksort($words);    # Сортируем все уникальные слова по алфавиту

foreach($words as $w=>$v){     # Вынесем в отдельный массив только редкие слова (которых в книге 1-5)
	if($v<=5){
		$rare_words[$w]=$v;
	}
}

$w_total = sizeof($rare_words);			# Посчитаем количество редких слов и запишем его в файл
$src = fopen('total.txt','w');
fwrite($src, $w_total);
fclose($src);

$src_trns = fopen('translated.txt','a');		# Создадим файл, куда будут помещаться переведенные слова

$cnt=0;
foreach($w_a as $w=>$v){     # Начнем перебирать слова

	if(!file_exists('flag')){  
		die();   # Если "файл - выключатель" не существует - прекратим исполнение скрипта
	}

/*
Следующая строка отправляет запрос на translate.yandex в виде обычного GET-запроса, где lang - языки перевода (с английского на русский), text - текст, который нуждается в переводе.
*/
	$arr = json_decode(file_get_contents('http://translate.yandex.net/api/v1/tr.json/translate?lang=en-ru&text='.$w,3), true);

	if($w!=$arr['text'][0]){     # Если Яндекс не вернул нам в точности то, что мы отправили ему
		fwrite($src_trns, $w.'|'.$arr['text'][0]."n");     # Запишем строку в файл словаря
	}
	$cnt++;   # Увеличим счетчик переведенных слов на единицу
	
	$src = fopen('current.txt','w');		# И запишем количество переведенных слов в файл
	fwrite($src, $cnt);
	fclose($src);

}
fclose($src_trns);
unlink('flag');     # После перевода всех слов уберем "выключатель" - это будет свидетельствовать о завершении
?>
stop.php

<?php
@unlink('flag');     # Просто удалим "выключатель", который чуть позже наш скрипт не найдет и прекратит исполнение
?>
index.html

<!DOCTYPE HTML>
<html>
<head>

<!-- Установим кодировку (обязательно) -->
<meta http-equiv="content-type" content="text/html; charset=UTF-8">     

<!-- Подключим библиотеку JQuery ( в примере использована в целях упрощения ) -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"  type="text/javascript"></script>

<script>

/*
Функция выводит состояние перевода
*/

function refresh(){
/* Получаем количество переведенных слов */
	$.post("current.txt",function(data) {
		current = data;
        });
/* Получаем количество всех слов и выводим в #status */
	$.post("total.txt",function(data) {
		$('#status').html(current+' / '+data);
	});
/* Ставим задержку перед выполнением этой функции заново */
        setTimeout(function(){
                refresh();
        }, 1000);
}

/*
Функция останавливает процесс перевода
*/

function stop(){
	$.post("stop.php");        /* Просто подергаем за stop.php, он выполнится и остановит процесс */
}

/*
Функция запускает процесс перевода
*/

function start(){
	$.post("handler.php");        /* Или же подергаем за handler.php, который начнет переводить книгу */
}

$('document').ready(function(){
	refresh();        /* После загрузки страницы вызываем функцию, которая обновляет состояние перевода */
});

</script>
</head>
<body>
<input type="button" value="Stop" onClick="stop();">
<input type="button" value="Start" onClick="start();">
<div id="status"></div>
</body>
</html>

Результаты

С помощью такого детского велосипеда перевел 5982 слов за 1033 секунды ( в среднем 5.78 слов в секунду ). Это относительно долго, отчасти потому, что я не выдумывал методы для ускорения перевода ( в идеале можно было отправлять несколько запросов одновременно, но мы ведь не хотим обидеть Яндекс ).

Данный пример можно использовать для перевода редких слов из книги или статьи, когда целью есть сам результат перевода, а не процесс. Если использовать в этих целях удаленный сервер, то процесс перевода будет происходить и при выключенном компьютере.

Автор: prineside

Поделиться

* - обязательные к заполнению поля