안녕하세요, 개발자 여러분! Python에서 Google 번역 기능을 구현할 때 가장 널리 사용되는 라이브러리 중 하나인 googletrans를 사용하다 보면 예상치 못한 문제에 부딪히곤 합니다. 특히 비동기(asyncio) 환경에서 번역이 제대로 되지 않고 원본 텍스트만 그대로 반환되는 ‘Is not translating’ 에러는 많은 개발자를 당황하게 만듭니다.
이번 포스팅에서는 이러한 googletrans 번역 실패 에러의 명확한 원인을 분석하고, 특히 asyncio와 함께 사용할 때 발생하는 문제점과 그에 대한 효과적인 해결 방법을 상세한 코드 예시와 함께 알아보겠습니다. 이 글을 통해 여러분의 프로젝트에서 googletrans를 안정적으로 사용할 수 있기를 바랍니다.
1. 에러 발생 상황
Stack Overflow에 올라온 문제 상황을 분석해보겠습니다. 개발자는 googletrans 라이브러리를 사용하여 스페인어 텍스트 ‘Hola mundo.’를 영어로 번역하려 했습니다. 아래 코드는 asyncio를 활용하여 비동기 함수 내에서 번역을 시도하는 예시입니다.
import asyncio
from googletrans import Translator
print("2 Googletrans tutorial: ")
async def translate_text():
async with Translator() as translator: # 이 부분은 잘못된 사용입니다.
print("async def 2 Googletrans tutorial: ")
translator = Translator() # 위에서 생성된 객체를 덮어씁니다.
result2 = await translator.translate('Hola mundo.', src='es', dest='en') # 동기 함수에 await 사용
print("2 Googletrans tutorial result2: ")
print(result2)
print(result2.text)
print(result2.extra_data)
asyncio.run(translate_text())
print("End of 2 Googletrans tutorial: ")
하지만 코드를 실행했을 때, 기대했던 번역 결과 대신 다음과 같은 출력을 받았습니다.
2 Tutorial googletrans:
async def 2 Tutorial googletrans:
2 Tutorial googletrans result2:
Translated(src=en, dest=en, text=Hola mundo., pronunciation=Hola mundo., extra_data="{'translat...")
Hola mundo.
{'translation': [['Hola mundo.', None, None, 0]], 'all-translations': None, 'original-language': 'en', 'possible-translations': None, 'confidence': 1, 'possible-mistakes': None, 'language': [['en'], None, [1], ['en']], 'synonyms': None, 'definitions': None, 'examples': None, 'see-also': None}
Fin 2 Tutorial googletrans:
출력을 보면 Translated(src=en, dest=en, text=Hola mundo., ...) 와 같이 번역이 전혀 이루어지지 않았고, 심지어 원본 언어가 스페인어(es)임에도 불구하고 영어(en)로 잘못 감지되었음을 알 수 있습니다. 이는 googletrans 라이브러리가 제대로 동작하지 않을 때 흔히 나타나는 현상입니다.
2. 명확한 발생 원인
이러한 ‘Is not translating’ 에러와 asyncio 환경에서의 오작동은 크게 두 가지 원인으로 볼 수 있습니다.
2.1. googletrans 라이브러리의 불안정성
googletrans 라이브러리는 Google 번역의 비공식 API를 스크래핑하는 방식으로 작동합니다. 즉, Google의 공식적인 API를 사용하는 것이 아니라, Google 번역 웹사이트의 내부 구조를 분석하여 데이터를 가져오는 방식입니다. 이로 인해 다음과 같은 문제가 발생할 수 있습니다.
- Google API 변경에 취약: Google이 번역 서비스의 내부 API나 웹 구조를 변경하면
googletrans는 더 이상 작동하지 않거나 오작동할 수 있습니다. - IP 차단 또는 요청 제한: 너무 많은 요청을 보내거나 비정상적인 접근으로 판단될 경우, Google에 의해 IP가 일시적으로 차단되어 번역이 실패할 수 있습니다.
- 오래된 버전: 라이브러리 버전이 오래되어 Google의 최신 변경 사항을 반영하지 못할 때도 문제가 발생합니다.
번역에 실패할 경우, googletrans는 종종 원본 텍스트를 그대로 반환하거나, 원본 언어를 en으로 잘못 감지하는 등의 오류를 반환합니다. 위 예시의 출력은 전형적인 googletrans의 번역 실패 증상입니다.
2.2. asyncio와 동기(Synchronous) 라이브러리 사용의 오해
가장 핵심적인 문제는 asyncio 기반의 비동기 코드 내에서 googletrans 라이브러리를 동기적으로 사용하는 방식에 있습니다.
Translator는 비동기 컨텍스트 관리자가 아닙니다:async with Translator() as translator:구문은Translator객체가 비동기 컨텍스트 관리자(asynchronous context manager)로 설계되지 않았기 때문에 올바르지 않습니다. 이 구문 자체는 제대로 작동하지 않거나, 의도치 않은 방식으로 객체를 초기화할 수 있습니다. (예시 코드에서는 바로 다음 줄에translator = Translator()가 있어 이 부분을 덮어쓰고 있습니다.)translate()메서드는 비동기가 아닙니다:googletrans.Translator의translate()메서드는 동기(Synchronous) 함수입니다. Python의asyncio환경에서는await키워드를 오직awaitable객체(코루틴, 퓨처 등)에만 사용할 수 있습니다. 동기 함수 앞에await를 붙이면 일반적으로TypeError: object ... has no attribute '__await__'와 같은 오류가 발생해야 합니다. 개발자 예시에서는 오류가 발생하지 않고 번역 실패 객체가 반환된 것이 특이하지만, 이는 내부적으로 비정상적인 처리가 있었거나 특정 환경에서의 예외적인 동작일 수 있습니다. 핵심은 동기 함수를 비동기 컨텍스트에서 직접await할 수 없다는 것입니다.
결론적으로, googletrans의 불안정성과 함께 asyncio 환경에서 동기 라이브러리를 잘못 사용하는 방식이 이 에러의 주된 원인입니다.
3. 해결 방법 및 코드 예시
이제 googletrans 번역 에러를 해결하고, asyncio 환경에서 안전하게 사용하는 방법을 알아보겠습니다.
3.1. googletrans 라이브러리 최신 버전 확인 및 업데이트
가장 먼저 시도해 볼 수 있는 방법은 googletrans 라이브러리를 최신 버전으로 업데이트하는 것입니다. 때때로 라이브러리 개발자들이 Google API 변경 사항에 대응하여 업데이트를 배포하기도 합니다.
pip install --upgrade googletrans==4.0.0rc1
googletrans는 불안정성이 높은 라이브러리이므로, 특정 버전(예: 4.0.0rc1)을 명시하여 설치하는 것이 더 안정적일 수 있습니다. 해당 버전은 비교적 최근까지 잘 작동했던 버전 중 하나입니다. 설치 후 다시 코드를 실행하여 번역이 되는지 확인해보세요.
3.2. asyncio 환경에서 동기 googletrans 함수 사용하기 (권장)
asyncio 애플리케이션 내에서 동기 함수를 안전하게 실행하려면 스레드 풀(thread pool)이나 프로세스 풀(process pool)을 이용해야 합니다. Python 3.9부터는 asyncio.to_thread()를, 그 이전 버전에서는 loop.run_in_executor()를 사용하는 것이 가장 깔끔한 해결책입니다.
3.2.1. Python 3.9 이상: asyncio.to_thread() 사용
asyncio.to_thread()는 동기 함수를 별도의 스레드에서 실행하고, 그 결과를 비동기적으로 기다릴 수 있게 해줍니다. 이 방법은 동기 라이브러리를 비동기 코드에 통합할 때 매우 유용합니다.
import asyncio
from googletrans import Translator
async def translate_text_correctly():
print("Corrected Googletrans tutorial (asyncio.to_thread):")
translator = Translator() # 동기 객체 생성
try:
# asyncio.to_thread를 사용하여 동기 함수를 별도 스레드에서 실행
result = await asyncio.to_thread(
translator.translate, 'Hola mundo.', src='es', dest='en'
)
print("Translation result:")
print(result)
print(f"Translated Text: {result.text}")
print(f"Source Language: {result.src}, Destination Language: {result.dest}")
except Exception as e:
print(f"An error occurred during translation: {e}")
print("Please check your internet connection or Googletrans version.")
asyncio.run(translate_text_correctly())
print("End of Corrected Googletrans tutorial.")
3.2.2. Python 3.9 미만: loop.run_in_executor() 사용
Python 3.9 미만 버전에서는 asyncio.get_event_loop().run_in_executor()를 사용해야 합니다. 이는 기본적으로 스레드 풀 executor를 사용합니다.
import asyncio
from googletrans import Translator
import concurrent.futures # Executor를 명시적으로 사용하고자 할 때
async def translate_text_executor():
print("Corrected Googletrans tutorial (run_in_executor):")
translator = Translator() # 동기 객체 생성
loop = asyncio.get_event_loop()
try:
# loop.run_in_executor를 사용하여 동기 함수를 스레드 풀에서 실행
# 첫 번째 인자는 executor 객체 (None이면 기본 ThreadPoolExecutor 사용)
# 두 번째 인자는 실행할 함수, 그 다음은 함수의 인자들
result = await loop.run_in_executor(
None, translator.translate, 'Hola mundo.', src='es', dest='en'
)
print("Translation result:")
print(result)
print(f"Translated Text: {result.text}")
print(f"Source Language: {result.src}, Destination Language: {result.dest}")
except Exception as e:
print(f"An error occurred during translation: {e}")
print("Please check your internet connection or Googletrans version.")
asyncio.run(translate_text_executor())
print("End of Corrected Googletrans tutorial.")
3.3. 대안 라이브러리 고려
프로덕션 환경이나 더욱 안정적인 번역 서비스가 필요한 경우, googletrans 대신 다음과 같은 대안을 고려해볼 수 있습니다.
- Google Cloud Translation API (공식): Google에서 제공하는 공식 번역 API로, 유료 서비스이지만 훨씬 더 안정적이고 고품질의 번역을 제공합니다.
- Deepl API: DeepL에서 제공하는 번역 API로, 특히 유럽 언어 번역에 강점을 보입니다. 공식 Python 클라이언트 라이브러리가 제공됩니다.
4. 향후 예방을 위한 팁
번역 라이브러리 사용 시 발생할 수 있는 문제를 예방하기 위한 몇 가지 팁입니다.
- 라이브러리 문서 숙지: 사용하는 라이브러리의 공식 문서를 항상 확인하여 비동기 지원 여부, 올바른 사용법 및 주의사항을 파악하세요.
- 비동기/동기 특성 이해: Python의
asyncio생태계에서 동기 함수와 비동기 함수의 차이점과 통합 방법을 명확히 이해하는 것이 중요합니다. 동기 함수는await할 수 없으며, 비동기 컨텍스트에서 실행하려면asyncio.to_thread()또는run_in_executor()를 사용해야 합니다. - 예외 처리 강화: 네트워크 요청이나 외부 API 호출을 포함하는 코드에는 항상 강력한 예외 처리(
try-except)를 추가하여 예기치 않은 오류에 대비해야 합니다. - API 기반 서비스 사용 고려: 비공식 라이브러리는 편리하지만, 프로덕션 환경에서는 안정성과 유지보수 측면에서 공식 API를 사용하는 것이 장기적으로 유리합니다.
이 글이 googletrans “Is not translating” 에러를 해결하고, Python 비동기 프로그래밍 환경에서 번역 기능을 구현하는 데 도움이 되기를 바랍니다. 궁금한 점이 있다면 언제든지 질문해주세요!
![[에러 해결] [Python asyncio] Redis PUB/SUB 장기 실행 TaskGroup 사용의 함정과 해결책 [에러 해결] [Python asyncio] Redis PUB/SUB 장기 실행 TaskGroup 사용의 함정과 해결책](https://dev-error.com/wp-content/plugins/contextual-related-posts/default.png)