使用Python调用Google Translate时遭遇SSL证书验证失败问题求助
SSL证书验证失败问题:使用googletrans调用Google Translate报错
我正在开发一个自动化多语言文本转换项目,基于Google Translate实现,已开发3-4个月,近期突然出现以下错误:
ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1129)
原代码
from googletrans import Translator, constants from pprint import pprint trans = Translator() translation = trans.translate(column_list, dest='en')
完整错误栈
Connect Error Traceback (most recent call last) Input In [155], in <cell line: 1>() ----> 1 translation=trans.translate(column_list,dest='en') File ~\Anaconda3\lib\site-packages\googletrans\client.py:205, in Translator.translate(self, text, dest, src, **kwargs) 203 result = [] 204 for item in text: --> 205 translated = self.translate(item, dest=dest, src=src, **kwargs) 206 result.append(translated) 207 return result File ~\Anaconda3\lib\site-packages\googletrans\client.py:210, in Translator.translate(self, text, dest, src, **kwargs) 207 return result 209 origin = text --> 210 data, response = self._translate(text, dest, src, kwargs) 212 # this code will be updated when the format is changed. 213 translated = ''.join([d[0] if d[0] else '' for d in data[0]]) File ~\Anaconda3\lib\site-packages\googletrans\client.py:108, in Translator._translate(self, text, dest, src, override) 104 params = utils.build_params(client=self.client_type, query=text, src=src, dest=dest, 105 token=token, override=override) 107 url = urls.TRANSLATE.format(host=self._pick_service_url()) --> 108 r = self.client.get(url, params=params) 110 if r.status_code == 200: 111 data = utils.format_json(r.text) File ~\Anaconda3\lib\site-packages\httpx_client.py:755, in Client.get(self, url, params, headers, cookies, auth, allow_redirects, timeout) 744 def get( 745 self, 746 url: URLTypes, (...) 753 timeout: typing.Union[TimeoutTypes, UnsetType] = UNSET, 754 ) -> Response: --> 755 return self.request( 756 "GET", 757 url, 758 params=params, 759 headers=headers, 760 cookies=cookies, 761 auth=auth, 762 allow_redirects=allow_redirects, 763 timeout=timeout, 764 ) File ~\Anaconda3\lib\site-packages\httpx_client.py:600, in Client.request(self, method, url, data, files, json, params, headers, cookies, auth, allow_redirects, timeout) 575 def request( 576 self, 577 method: str, (...) 588 timeout: typing.Union[TimeoutTypes, UnsetType] = UNSET, 589 ) -> Response: 590 request = self.build_request( 591 method=method, 592 url=url, (...) 598 cookies=cookies, 599 ) --> 600 return self.send( 601 request, auth=auth, allow_redirects=allow_redirects, timeout=timeout, 602 ) File ~\Anaconda3\lib\site-packages\httpx_client.py:620, in Client.send(self, request, stream, auth, allow_redirects, timeout) 616 timeout = self.timeout if isinstance(timeout, UnsetType) else Timeout(timeout) 618 auth = self.build_auth(request, auth) --> 620 response = self.send_handling_redirects( 621 request, auth=auth, timeout=timeout, allow_redirects=allow_redirects, 622 ) 624 if not stream: 625 try: File ~\Anaconda3\lib\site-packages\httpx_client.py:647, in Client.send_handling_redirects(self, request, auth, timeout, allow_redirects, history) 644 if len(history) > self.max_redirects: 645 raise TooManyRedirects() --> 647 response = self.send_handling_auth( 648 request, auth=auth, timeout=timeout, history=history 649 ) 650 response.history = list(history) 652 if not response.is_redirect: File ~\Anaconda3\lib\site-packages\httpx_client.py:684, in Client.send_handling_auth(self, request, history, auth, timeout) 682 request = next(auth_flow) 683 while True: --> 684 response = self.send_single_request(request, timeout) 685 if auth.requires_response_body: 686 response.read() File ~\Anaconda3\lib\site-packages\httpx_client.py:714, in Client.send_single_request(self, request, timeout) 705 transport = self.transport_for_url(request.url) 707 try: 708 ( 709 http_version, 710 status_code, 711 reason_phrase, 712 headers, 713 stream, --> 714 ) = transport.request( 715 request.method.encode(), 716 request.url.raw, 717 headers=request.headers.raw, 718 stream=request.stream, 719 timeout=timeout.as_dict(), 720 ) 721 except HTTPError as exc: 722 # Add the original request to any HTTPError unless 723 # there'a already a request attached in the case of 724 # a ProxyError. 725 if exc._request is None: File ~\Anaconda3\lib\site-packages\httpcore_sync\connection_pool.py:152, in SyncConnectionPool.request(self, method, url, headers, stream, timeout) 149 logger.trace("reuse connection=%r", connection) 151 try: --> 152 response = connection.request( 153 method, url, headers=headers, stream=stream, timeout=timeout 154 ) 155 except NewConnectionRequired: 156 connection = None File ~\Anaconda3\lib\site-packages\httpcore_sync\connection.py:65, in SyncHTTPConnection.request(self, method, url, headers, stream, timeout) 61 if not self.socket: 62 logger.trace( 63 "open_socket origin=%r timeout=%r", self.origin, timeout 64 ) --> 65 self.socket = self._open_socket(timeout) 66 self._create_connection(self.socket) 67 elif self.state in (ConnectionState.READY, ConnectionState.IDLE): File ~\Anaconda3\lib\site-packages\httpcore_sync\connection.py:85, in SyncHTTPConnection._open_socket(self, timeout) 83 ssl_context = self.ssl_context if scheme == b"https" else None 84 try: --> 85 return self.backend.open_tcp_stream( 86 hostname, port, ssl_context, timeout 87 ) 88 except Exception: 89 self.connect_failed = True File ~\Anaconda3\lib\site-packages\httpcore_backends\sync.py:139, in SyncBackend.open_tcp_stream(self, hostname, port, ssl_context, timeout) 135 if ssl_context is not None: 136 sock = ssl_context.wrap_socket( 137 sock, server_hostname=hostname.decode("ascii") 138 ) --> 139 return SyncSocketStream(sock=sock) File ~\Anaconda3\lib\contextlib.py:137, in _GeneratorContextManager.exit(self, typ, value, traceback) 135 value = typ() 136 try: --> 137 self.gen.throw(typ, value, traceback) 138 except StopIteration as exc: 139 # Suppress StopIteration unless it's the same exception that 140 # was passed to throw(). This prevents a StopIteration 141 # raised inside the "with" statement from being suppressed. 142 return exc is not value File ~\Anaconda3\lib\site-packages\httpcore_exceptions.py:12, in map_exceptions(map) 10 for from_exc, to_exc in map.items(): 11 if isinstance(exc, from_exc): --> 12 raise to_exc(exc) from None 13 raise ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1129)
已尝试的无效方法
- 创建未验证SSL上下文:
import ssl import urllib.request context = ssl._create_unverified_context() urllib.request.urlopen(trans, context=context)
- 设置requests会话不验证证书:
session = requests.Session() session.verify = False
解决方案
方案1:为googletrans配置httpx客户端跳过SSL验证
googletrans底层使用httpx而非requests,因此之前设置requests会话的方法无效。需创建禁用SSL验证的httpx客户端传入Translator:
from googletrans import Translator import httpx # 创建不验证SSL的httpx客户端 client = httpx.Client(verify=False) trans = Translator(client=client) translation = trans.translate(column_list, dest='en')
注意:此方法会降低安全性,仅适合测试或内部可信环境使用。
方案2:导入系统根证书(推荐)
若问题由公司代理的自签名证书导致,可将代理证书添加到Python信任列表:
- 导出代理的自签名证书为
.pem格式 - 在代码中指定证书路径:
from googletrans import Translator import httpx client = httpx.Client(verify="/path/to/your/certificate.pem") trans = Translator(client=client) translation = trans.translate(column_list, dest='en')
也可将证书添加到系统根证书存储,Python会自动加载系统信任的证书。
方案3:降级googletrans版本
部分新版本googletrans的httpx适配存在问题,可尝试降级到稳定版本:
pip install googletrans==4.0.0-rc1
该版本基于requests库开发,此时设置session.verify=False会生效:
from googletrans import Translator import requests session = requests.Session() session.verify = False trans = Translator(session=session) translation = trans.translate(column_list, dest='en')
内容的提问来源于stack exchange,提问作者user47341
相关产品推荐
相关产品推荐

