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. 11 Март 2010 в 20:19 | #1
    я еще не слышал чтоб кого-то забанили ни за первое ни за второе
Страницы комментариев
Комментирование отключено.