Google Translate

28 Август 2008

Сейчас пытаюсь возродить свой бывший сайт под названием ForbidenWish. Там много книг и вносить их в БД вручную я не собираюсь, поэтому написал небольшой скрипт который обходит директории, парсит имена файлов и заносит их в базу. Вот в один момент я понял что простая транслитерация названия книги это не интересно, а иногда и глупо получалось, и я вспомнил про форум ДКлаб у них там при создании темы заголовок переводиться на английски (причем весьма неплохо) и подставляется в url. Я практически уверен что Котеров не писал переводчик и просто пользуется каким-то сервисом, первое что мне пришло в голову - Google. Сначала думал парсить html страницу но потом понял что там все намного проще и перевод забирается javascript'ом, В общем после непродолжительных изысканий я придумал вот эту функцю.


function translate($str, $from='ru', $to='en'){
	$fp = fsockopen("www.google.com", 80, $errno, $errstr, 30);
	if (!$fp) {
		trigger_error("$errstr ($errno)<br />\n", E_USER_WARNING);
		return "";
	} else {
		$out = "GET /translate_a/t?client=t&sl=".$from."&tl=".$to."&text=".urlencode($str)." HTTP/1.1\r\n";
		$out .= "Host: www.google.com\r\n";
		$out .= "User-Agent: Mozilla/5.0\r\n";
		$out .= "Accept-Encoding: deflate\r\n";
		$out .= "Connection: Close\r\n\r\n";
		
		fputs($fp, $out);
		$res = "";
		while (!feof($fp)) {
			$res .=  fgets($fp, 1024);
		}
		fclose($fp);
	}
	
	$res = explode("\r\n\r\n",$res);
	$res = explode("\r\n",$res[1]);
	return stripslashes(substr($res[1],1,-1));
}

Но таким образом гугл отказывается переводить больше чем 2 килобайта текста, если нудно переводить большие объемы по нужно использовать пост запрос


function translate($str, $from='en', $to='ru'){
	$fp = fsockopen("www.google.com", 80, $errno, $errstr, 30);
	if (!$fp) {
		trigger_error("$errstr ($errno) \n", E_USER_WARNING);
		return "";
	} else {
		$text = "text=".urlencode($str);
		$out = "POST /translate_a/t?client=t&sl=".$from."&tl=".$to." HTTP/1.1\r\n";
		$out .= "Host: www.google.com\r\n";
		$out .= "User-Agent: Mozilla/5.0\r\n";
		$out .= "Accept-Encoding: deflate\r\n";
		$out .= "Content-length: ".strlen($text)."\r\n";
		$out .= "Connection: Close\r\n\r\n";
		$out .= $text;
		
		fputs($fp, $out);
		$res = "";
		while (!feof($fp)) {
			$res .=  fgets($fp, 1024);
		}
		fclose($fp);
	}
	
	$res = explode("\r\n\r\n",$res);
	$res = explode("\r\n",$res[1]);
	return stripslashes(substr($res[1],1,-1));
}

Так можно обработать до 32 килобайт за раз!

Если кому пригодиться - оставьте коммент!

UPD Реализация на С++ от Lupascu Ion с небольшой доработкой от меня


String GoogleTranslator::TranslateText(String from, String to){
	//... need to add proxy
	//http_client.Proxy("");
	String url = "www.google.com/translate_a/t?client=t&sl=" + from + "&tl=" + to + "&ie=utf-8&oe=utf-8";
	http_client.URL(url);
	//http_client.Agent("Mozilla/5.0");
	http_client.TimeoutMsecs(5000);
	http_client.Post();
	http_client.PostData(String("text=").Cat()<<UrlEncode(inputwindow.textfrom.Get(CHARSET_UTF8)));
	//http_client.Headers("Accept-Encoding: deflate\r\n");
	String result = http_client.ExecuteRedirect();
	
	if (!IsNull(result)){
		if(result.StartsWith("\"")){// is string
			result.Remove(0, 1);
			result.Remove(result.GetLength()-1, 1);
		}
		else{ // is terms
			//... need to parse terms
		};
		
		return result;
	}
	else
		return String("Error:").Cat()<<Nvl(http_client.GetError(), "")
			<<"\n, status: "<<http_client.GetStatusCode()<<", "<<http_client.GetStatusLine()
			<<"\n, header: "<<http_client.GetHeaders();
}

UPD Есть предложение вместо


return stripslashes(substr($res[1],1,-1));
возвращать

return json_decode($res[1]);
Но на этом сраном хостинге с тех пор как им занимается компания HostBizUa перестали ставить свежие версии ПО, и у меня стоит древний PHP 5.1.6 в котором этой функции нет, поэтому я использую такое мудачество чтобы со словарем проблем не было.

return substr($res[1],0,1) == '[' ?
	substr($res[1],2,strpos($res[1],'"',2)-2) :
	substr($res[1],1,-1);
  1. 28 Август 2008 в 12:22 | #1
    Полезная штука :) Заюзаю у себя.
  2. Dfc
    3 Ноябрь 2008 в 13:09 | #2
    Пригодилось
  3. 1 Январь 2009 в 03:45 | #3
    http://adw0rd.ru/2009/google-non-ajax-language-api/ Зацени! :-)
  4. 18 Январь 2009 в 13:44 | #4
    я думаю корретнее будет использовать API http://aplabs.ru/2008/12/05/hello-world/ http://livepad.ru/view/0e12972c
  5. 19 Январь 2009 в 17:06 | #5
    VitCOM SEO, а чем корретнее?))
  6. 16 Февраль 2009 в 12:00 | #6
    Да, действительно. Спасибо, буду пользоваться. Может, попробую расширить функционал ;)
  7. 22 Февраль 2009 в 10:45 | #7
    Функционал не расширил, но переписал на C++ и QT: http://alexsnet.ru/2009/02/google-translate-non-ajax-api/
  8. Антон
    26 Февраль 2009 в 19:14 | #8
    У меня второй вариант функции работает секунд 10. Это нормально?
  9. Антон
    26 Февраль 2009 в 19:15 | #9
    для меня время критично
  10. 26 Февраль 2009 в 22:28 | #10
    странно, у меня все быстро работает
  11. 3 Март 2009 в 12:53 | #11
    Искал Zend Translate, случайно нашел Google Translate. Почитал, спасибо, может пригодится.
  12. Lupascu Ion
    18 Март 2009 в 10:01 | #12
    Пытался перевести из "ru" в "en" слово "Привет"... но возвращает текст "??????" post method и "Ïðèâåò" get method. кодировка utf-8!
  13. 18 Март 2009 в 10:40 | #13
    @Lupascu Ion На страницу на которой ты тестируешь добавь мета таг с указанием кодировки :)
  14. Lupascu Ion
    18 Март 2009 в 10:40 | #14
    Решить проблему можно добавить в адрес и текст "&ie=utf-8&oe=utf-8"
  15. Lupascu Ion
    18 Март 2009 в 10:43 | #15
    @CTAPbIu_MABP Спасибо! но я тестировал для с++ внешние! Идея очень интересное! могу поделиться с приложение! работает отлично!
  16. 18 Март 2009 в 10:51 | #16
    делись, буду очень рад. но если ты не видел то Alex Snet уже переписал для QT, линк в трэкбэке.
  17. Lupascu Ion
    18 Март 2009 в 10:55 | #17
    Видел... но не уверен что работает без "&ie=utf-8&oe=utf-8". Я мучалься пару часов пока не нашел в инете у японцы! Где могу выслать бинарник и/или исходники?
  18. 18 Март 2009 в 11:01 | #18
    ctapbiumabp@gmail.com - исходник. если ты не против я в статью добавлю?
  19. Lupascu Ion
    18 Март 2009 в 11:09 | #19
    Не против, конечно! Пусть народ знает! Хотелось добавить возможность интеграции механизма Google suggestion! Исходники можешь взять по аддресу http://www.ultimatepp.org/forum/index.php?t=rview&goto=20425&th=4239#msg_20425 А win32 бинарники вышлю на e-mail! Исходники можно компилить на win32, Linux и, наверно, MacOS!
  20. 18 Март 2009 в 11:33 | #20
    Надеюсь я правильно поправил твой код :) а что за механизм Google suggestion? может Google dictionary для перевода одного слова? ну я сейчас по колдую и на Java что-то набросаю.
  21. 18 Март 2009 в 11:36 | #21
    И поставь плз на форуме ссылку откуда код взят :)
  22. Lupascu Ion
    18 Март 2009 в 11:43 | #22
    @CTAPbIu_MABP Самое главное что понятно! http_client.Agent("Mozilla/5.0"); и http_client.Headers("Accept-Encoding: deflate\r\n"); лишнее, удали! Ставить ссылку на тот форум где ставил твои исходники?
  23. 18 Март 2009 в 12:39 | #23
    ок, удалю тока объясни почему. нет на форуме так где код напиши что взял его отсюда)))
  24. Lupascu Ion
    18 Март 2009 в 12:51 | #24
    Ссылку добавил! Те две строки лишнее, потому-что по умольчание добовляет class HttpClient! "Accept-Encoding: gzip\r\n" и "Agent: Ultimate++ HTTP client"
  25. 18 Март 2009 в 13:26 | #25
    спасибо, сейчас буду выкладывать версию для Java - поправлю.
  26. Lupascu Ion
    19 Март 2009 в 10:28 | #26
    Есть кто знает как можно отпровлять исправленный перевод на google suggestion? Нашел адрес http://translate.google.com/translate_suggestion но не уверен!
  27. 19 Март 2009 в 10:46 | #27
    вчера не вышло закончить переводчик на Java, думаю сегодня закончу, зато я каменты поправил чтоб обрывы строк были видны на этот адрес надо присылать пост запрос gtrans=whazzup&hl=ru&langpair=ru|en&oe=UTF-8&text=превед&utrans=wazzup но думаю что langpair=ru|en можно заменить на sl=ru&tl=en
  28. Lupascu Ion
    19 Март 2009 в 11:33 | #28
    Спасибо! По переводу я правельно понял? По логике вижу так? gtrans=&hl=ru&langpair=ru|en&oe=UTF-8&text=&utrans=
  29. Lupascu Ion
    19 Март 2009 в 11:35 | #29
    По переводу я правельно понял? По логике вижу так? gtrans=ТекстПереведенОтГугл&hl=ru&langpair=ru|en&oe=UTF-8&text=ИсходныйТекст&utrans=ТекстПереведенОтПользователя
  30. 19 Март 2009 в 12:19 | #30
    да правильно
  31. Lupascu Ion
    19 Март 2009 в 13:43 | #31
    @CTAPbIu_MABP Хотел уточнить хост какой? www.google.com/translate_a/t?client=t или http://translate.google.com/translate_suggestion/? ?
  32. 19 Март 2009 в 14:21 | #32
    если я не ошибаюсь они идентичны
  33. Lupascu Ion
    20 Март 2009 в 22:46 | #33
    Не думаю! если просто открыть в броузер... то второе ссылку не работает!
  34. 20 Март 2009 в 23:27 | #34
    потому что это не директория. надо убрать слеш в конце
  35. Андрей
    31 Март 2009 в 12:29 | #35
    По поводу кодировки: может оно и понятно сразу, но с час про..занимался, пока понял, что строку нужно подавать в юникоде. Например (при странице с кодировкой windows-1251): echo iconv("UTF-8", "windows-1251",translate(iconv("windows-1251", "UTF-8","строка"),'ru','uk'));
  36. 31 Март 2009 в 15:06 | #36
    я думал это общеизвестный факт, что Гугл использует только UTF-8 и даже все проиндексированные страницы переводит в эту кодировку
  37. 10 Апрель 2009 в 23:50 | #37
    Люди блин добрые всем здарова! Нужна ваша помощь....3-й день мозг себе надрываю читая ваши коменты, этот пост и аналогичных штуки 3-4.......помогите разобраться.... Нужно перевести статью например: [text] [text] [text] так как она есть...т.е. с расстановкой переносов строк (\r\n).... пытался переводить вторым вариантом с помощью POST -> вот результат: [text]\n\n[text]\n\n[text] эт не то, что хотелось.... нада, чтобы получилось приблизительно вот что: [text] [text] [text] нада переделать эту функцию Спасайте....вся надежда на Вас!!!:))
  38. 11 Апрель 2009 в 00:01 | #38
    Прости но я твой камент порезал уж очень длинный был.
  39. 11 Апрель 2009 в 00:02 | #39
    @CTAPbIu_MABP Не страшно......одно забыл сказать....скрипт отсылает приличный кусок текста, а обратно возвращается какой-то странный, порезанный на куски и не весь......надо шоб бал весь....
  40. 11 Апрель 2009 в 00:06 | #40
    я только что попробовал вариант с return json_decode($res[1]); у меня переносы строк остались попробуй пропустить перевод через nl2br может тебе это нужно а что за куски?
  41. 11 Апрель 2009 в 00:08 | #41
    кста у меня на вдс return json_decode($res[1]); не пашет..... как сделать, чтобы пахал??? что нужно включить? я даж не знаю, что эт......разъясни немного плз.........мож у мну и заработает как надо
  42. 11 Апрель 2009 в 00:10 | #42
    тебе надо установить свежую версию php версия с stripslashes(substr($res[1],1,-1)); тоже прекрасно пашет пришли мне на мыло весь текст ctapbiumabp@gmail.com
  43. 11 Апрель 2009 в 00:14 | #43
    отправил...
  44. 11 Апрель 2009 в 00:17 | #44
    Пхп стоит: php5-5.2.9 вроде не старый.......или я ошибаюсь?
  45. 11 Апрель 2009 в 00:17 | #45
    у меня все переносы остались %)
  46. 11 Апрель 2009 в 00:19 | #46
    php самый свежий модет тебе просто потом ответ пропускать через str_replace('\n\n',"\r\n",$text); ?
  47. 11 Апрель 2009 в 00:24 | #47
    т.е.? можешь функцию переписать, шоб работала... она вреде всё равно по 32кб не отсылает..... я вот думаю мож кусками.....по абзацам...можешь такое сотворить? я с гуглой два дня назад ток разбираться начал...поэтому можно сказать в этом нуб:))
  48. 11 Апрель 2009 в 00:36 | #48
    не пашет всё равно...
  49. 11 Апрель 2009 в 00:38 | #49
    ну все верно str_replace('rnrn',"\r\n",translate($text)); пробуй это
  50. 11 Апрель 2009 в 00:44 | #50
    Во эт работает.........а ток текст не весь.....вторая половина текста теряется.... как эт можно исправить?
Страницы комментариев
Комментирование отключено.