В данной теме я попытаюсь описать один из способов получения перевода текстов в виде написания php-скрипта, который далее мы будем использовать на нашем сайте. Если выразиться точнее, то мы разберёмся в том, как написать функцию перевода, которую можно использовать в любом php-скрипте.
Небольшое вступление.
Существует множество скриптов, предназначенных для перевода текста на различные языки. В них используются API различных сервисов, предоставляющих перевод текстов. У всем известной поисковой системы Google так же существует сервис перевода текстов, и до недавнего времени при использовании API переводчика Google было всё нормально, пока, как это обычно и бывает, Google не стал предоставлять эту услугу платно и брать за это денежку. Допустим мы не имеем лишних денег для покупки ключа, но всё же нам необходимо переводить именно гуглем. Будем искать выход. Как известно у гугла имеется так же и онлайн переводчик, в котором так же можно переводить тексты, но делается это всё на страничке переводчика гугла. Но ведь эта страница при переводе текста должна отправлять изначальный текст в свой переводчик и получать от него результат перевода, который и выведется нам в браузер, и делает она это всё бесплатно.
Итак, выход мы уже увидели, нужно всего-навсего сымитировать действия странички гугла, отправить наш текст так же, как это делает страница переводчика, и получить результат перевода обратно в нашу программу.
Если в вашем браузере не отключен JavaScript, то перевод производится с его помощью без перезагрузки страницы, но гугл же серьёзная компания, и конечно же предусмотрела все случаи, в том числе и случай, когда у пользователя в браузере отключен JavaScript. Давайте отключим JavaScript в настройках браузера и снова зайдём на страничу переводчика. Страничка немного видоизменилась. Теперь посмотрим что происходит при переводе текста, напишем какое-нибудь предложение и нажмём "перевести", страничка перезагрузилась, мы получили опять же страницу переводчика, но уже с переводом. Смотрим в строку url, кроме translate.google.ru мы больше ничего не видим, следовательно гугл отправил себе наш текст из формы POST-запросом и отобразил новую страницу с результатом перевода.
Теперь нам нужно узнать, что же за значения отправляются из формы, для этого давайте просмотрим в браузере код элемента(формы), думаю понятно как это делать, потому объяснять не буду и сразу опишу то, что мы должны увидеть. Мы видим, что html нашей формы состоит из очень большого количества строк. В первую очередь нас интересует вот эта:
PHP код:
<form id="gt-form" action="/" name="text_form" method="post" enctype="application/x-www-form-urlencoded">
Отсюда мы видим, что страница отправляет содержимое формы самой же себе методом POST. Теперь мы точно знаем куда и как отправлять. Теперь разберёмся ЧТО отправлять.
Смотрим на элементы формы. Здесь имеется множество различных элементов. Выделим самые важные. такие как теги select - элементы для выбора языка текста:
PHP код:
<select id="gt-sl" name="sl" class="jfk-button jfk-button-standard nje" tabindex="0"> ...
и языка перевода:
PHP код:
<select id="gt-tl" name="tl" class="jfk-button jfk-button-standard nje" tabindex="0"> ...
Собственно наш текст:
PHP код:
<textarea id="source" name="text" wrap="SOFT" tabindex="0" dir="ltr" spellcheck="false" autocapitalize="off" autocomplete="off" autocorrect="off">Maша ела кашу. Петя гулял с Наташей. Мама мыла Машу с Петей.</textarea>
И тег span, содержащий наш перевод, точнее один основной span с несколькими вложенными:
PHP код:
<span id="result_box" class="long_text">
<span title="Maша ела кашу." onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">
Masha was eating porridge.
</span>
<span title="Петя гулял с Наташей." onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">
Peter walked with Natasha.
</span>
<span title="Мама мыла Машу с Петей." onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">
Mom Soap Masha and Petya.
</span>
</span>
Так же тут есть множество элементов input, у которых присутствует hidden, то есть они нам не видны, но тоже нужны, и их значения тоже отправляются в запросе.
Как известно, при отправке содержимого формы строка запроса будет представлять собой адрес странички и параметры. Имя параметра - это name элемента формы, значение параметра - это value элемента формы, либо его "внутренности", в зависимости от того, что это за элемент, например input или textarea. Рассмотрев внимательно код формы выделим все параметры которые должны будут отправиться. Приведу сразу их список, так как весь текст слишком громоздкий:
'sl' - это первый элемент select, язык нашего текста, значение его будет в зависимости от выбранного option, соответствие значения и языка можно посмотреть прямо в коде формы, мы установим в 'ru'
'tl' - это язык перевода, второй элемент select, мы укажем 'en'
'js' - значение должно быть установлено в 'n', так как всё происходит без использования JavaScript
'prev' - ну правда, хз что это за параметр
он скрытый на форме и установлен в '_t', так и поступим
'hl' - этот параметр говорит гуглу о том, на каком языке нужно возвращать саму страницу в браузер, мы установим в 'ru', хотя это и не важно, нам нужна не вся страница полностью, а только отображаемый на ней перевод. Пусть сама страница будет хоть на китайском, главное перевод на нужном нам языке.
'ie' - судя по установленному значению, кодировка текста, значение устанавливаем в 'UTF-8',
'layout' - не знаю, знать не хочу и не важно
- установлено в '2', так и поступим.
'eotf' - анологично предыдущему, установлено в '1'.
'text' - собственно наш текст, который нужно перевести
'file' - отправляется пустым значением, возможно нужен для указания того, что результат нужно записать в файл.
Нам нужно делать этот запрос в ходе выполнения нашей программы, а не так же, как на странице переводчика, иначе наша затея безполезна.
Для POST запросов можно пользоваться AJAX, а мы воспользуемся cURL, так как нам нужен php скрипт на сервере.
Итак, начнём написание нашего скрипта. Я не буду писать текст всего php-файл, так как он у каждого может быть свой а может быть вынесен в отдельный php-файл, так сказать в виде модуля. Мы напишем только функцию, которая нами используется в этом скрипте и которая осуществляет перевод. В эту функцию передаётся наш текст, а возвращается текст перевода:
PHP код:
<?php
function trns($text)
{
sleep (1); // это для того, чтобы не грузить сервер гугла слишком частыми запросами, у нас будет задержка в секунду. Эту строку можно убрать
$user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.2.13) '.'Gecko/20101203 Firefox/3.6.13 ( .NET CLR 3.5.30729)';
$url='http://translate.google.ru/'; // адрес нашего переводчика
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true); // true т.к. мы будем отправлять post запрос
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); // чтобы сайт принял нас за браузер
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // ответ сервера будем записывать в переменную
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // максимальное время нашего сеанса в секундах
curl_setopt($ch, CURLOPT_URL, $url); // задаём url
//Для наглядности запишем все параметры запроса массивом
$post = array(
'sl' => 'ru',
'tl' => 'en',
'js' => 'n',
'prev' => '_t',
'hl' => 'ru',
'ie' => 'UTF-8',
'layout' => '2',
'eotf' => '1',
'text' => $text,
'file' => ''
);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post)); // итак, создали наш запрос..
$answer = curl_exec($ch); // выполним его, а ответ переводчика получим в переменную $answer
curl_close($ch);
Итак мы получили результат, что он из себя представляет? А представляет он из себя html-текст всей страницы, которая должна была по сути отобразиться в браузере, и этот текст помещён в переменную $ansver. Но нам не нужна вся страница, а нужен только перевод, потому мы будем парсить эту текстовую переменную, и вырежем из неё текст перевода. Как я указывал ранее, на странице присутствует тег span:
PHP код:
<span id="result_box" class="long_text">
<span title="Maша ела кашу." onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">
Masha was eating porridge.
</span>
<span title="Петя гулял с Наташей." onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">
Peter walked with Natasha.
</span>
<span title="Мама мыла Машу с Петей." onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">
Mom Soap Masha and Petya.
</span>
</span>
Он содержит наш перевод. Но, как мы видим, в этом тэге вложено ещё несколько тегов span, содержащих куски перевода. То есть нам вернулся перевод, разрезанный на куски, которые помещены в тэги span. Нам предстоит "вырезать" эти куски и склеить в один текст. Воспользуемся регулярными выражениями и распарсим текстовую переменную $answer.
PHP код:
preg_match("~<span id=result_box class=\"[^\"]*\">(.*?)</span></div~",$answer,$mass);
Результат парсинга помещается в массив $mass, в котором нужен один элемент под индексом 1(в нулевом элементе должна получиться вся страница)
Регулярное выражение говорит о том, что нам нужен кусок текста:
1)после тега span с id равным result_box
2)class равен любому тексту, заключённому в кавычки(на случай если гугловцы изменят его имя)
3)после куска текста сделует закрывающий тег span, после которого сразу же идёт закрывающий div
Совпадением будет только один кусок на всей странице, и будет состоять из нескольких тегов span, содержащих перевод, а именно:
PHP код:
<span title="Maша ела кашу." onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">
Masha was eating porridge.
</span>
<span title="Петя гулял с Наташей." onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">
Peter walked with Natasha.
</span>
<span title="Мама мыла Машу с Петей." onmouseover="this.style.backgroundColor='#ebeff9'" onmouseout="this.style.backgroundColor='#fff'">
Mom Soap Masha and Petya.
</span>
Теперь нам нужно "вытащить" сам текст из этих span.
PHP код:
preg_match_all("~>([^<]*)~",$mass[1],$mass);
Регулярное выражение говорит о том, что нужно вернуть все куски, которые идут после закрывающей скобки '>' и до первой встречной открывающей '<', это и будут все куски текста, содержащиеся в нескольких span.
Мы берём все совпадения(все куски перевода) и поместим в этот же массив, элементами массива теперь будут куски текста.
Остаётся склеить их в один текст и вернуть из функции.
$result="";
for ($n=0; $n<count($mass[1]); $n++)
{
$result.= $mass[1][$n]; // суммируем кусок ко всему тексту в цикле
}
return $result;
}
Вот так мы написали функцию перевода через переводчик Google текста любого обьёма и на халявной основе
Ниже её текст полностью.
PHP код:
function trns($text)
{
sleep (1);
$user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.2.13) '.'Gecko/20101203 Firefox/3.6.13 ( .NET CLR 3.5.30729)';
$url='http://translate.google.ru/';
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
curl_setopt($ch, CURLOPT_URL, $url);
$post = array(
'sl' => 'en',
'tl' => 'ru',
'js' => 'n',
'prev' => '_t',
'hl' => 'ru',
'ie' => 'UTF-8',
'layout' => '2',
'eotf' => '1',
'text' => $text,
'file' => ''
);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$answer = curl_exec($ch);
curl_close($ch);
preg_match("~<span id=result_box class=\"[^\"]*\">(.*?)</span></div~",$answer,$mass);
preg_match_all("~>([^<]*)~",$mass[1],$mass);
$result="";
for ($n=0; $n<count($mass[1]); $n++)
{
$result.= $mass[1][$n];
}
return $result;
}