英文:
Why can't I access the Google Translate API via IP?
问题
I'm here to assist with the translation. Here's the translated content:
我正在尝试使用`urllib`库通过IP访问Google翻译API,如下所示:
```python
from urllib.request import Request, urlopen
import ssl
ip = '142.250.1.90'
HOST = 'translate.googleapis.com'
URL_FORMAT = 'https://{}/translate_a/single?client=gtx&sl=en&tl=fr&q=a'
def _build_request(ip):
url = URL_FORMAT.format(ip)
request = Request(url)
request.add_header('Host', HOST)
return request
urlopen(_build_request(ip), timeout=2.5, context=ssl._create_unverified_context()).close()
但我遇到了这个错误:
urllib.error.URLError: <urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)>
如何修复它?
我在网上找到的所有现有解决方案都没有起作用(ChatGPT也没有解决)。
<details>
<summary>英文:</summary>
I'm trying to access the Google Translate API via IP with the `urllib` library as follows:
```python
from urllib.request import Request, urlopen
import ssl
ip = '142.250.1.90'
HOST = 'translate.googleapis.com'
URL_FORMAT = 'https://{}/translate_a/single?client=gtx&sl=en&tl=fr&q=a'
def _build_request(ip):
url = URL_FORMAT.format(ip)
request = Request(url)
request.add_header('Host', HOST)
return request
urlopen(_build_request(ip), timeout=2.5, context=ssl._create_unverified_context()).close()
But I got this error:
urllib.error.URLError: <urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)>
How to fix it?
All the existing solutions which I found on the web did not work (ChatGPT didn't solve it either).
答案1
得分: 2
I suspect that the remote endpoint requires the client to correctly set the SNI value in the SSL request. There's no built-in to do this other than by providing the correct hostname in your request.
We can monkey patch the SSL context to explicitly set the server hostname by doing something like this:
from urllib.request import Request, urlopen
import ssl
ip = "142.250.1.90"
HOST = "translate.googleapis.com"
URL_FORMAT = "https://{}/translate_a/single?client=gtx&sl=en&tl=fr&q=a"
def _build_request(ip):
url = URL_FORMAT.format(ip)
request = Request(url)
request.add_header("Host", HOST)
return request
def patch_context(ctx, server_hostname):
old_wrap_socket = ctx.wrap_socket
def new_wrap_socket(socket, **kwargs):
kwargs["server_hostname"] = server_hostname
return old_wrap_socket(socket, **kwargs)
ctx.wrap_socket = new_wrap_socket
req = _build_request(ip)
ctx = ssl._create_unverified_context()
patch_context(ctx, HOST)
with urlopen(req, timeout=2.5, context=ctx) as response:
print(response.read())
In the above code, we're replacing the wrap_socket
method of the SSL context with a new method that sets the server_hostname
parameter to our desired value.
Running this code successfully performs the request; the output of the final print()
statement is:
b'[null,null,"en",null,null,null,null,[]]'
英文:
I suspect that the remote endpoint requires the client to correctly set the SNI value in the SSL request. There's no built-in to do this other than by providing the correct hostname in your request.
We can monkey patch the SSL context to explicitly set the server hostname by doing something like this:
from urllib.request import Request, urlopen
import ssl
ip = "142.250.1.90"
HOST = "translate.googleapis.com"
URL_FORMAT = "https://{}/translate_a/single?client=gtx&sl=en&tl=fr&q=a"
def _build_request(ip):
url = URL_FORMAT.format(ip)
request = Request(url)
request.add_header("Host", HOST)
return request
def patch_context(ctx, server_hostname):
old_wrap_socket = ctx.wrap_socket
def new_wrap_socket(socket, **kwargs):
kwargs["server_hostname"] = server_hostname
return old_wrap_socket(socket, **kwargs)
ctx.wrap_socket = new_wrap_socket
req = _build_request(ip)
ctx = ssl._create_unverified_context()
patch_context(ctx, HOST)
with urlopen(req, timeout=2.5, context=ctx) as response:
print(response.read())
In the above code, we're replacing the wrap_socket
method of the SSL context with a new method that sets the server_hostname
parameter to our desired value.
Running this code successfully performs the request; the output of the final print()
statement is:
b'[null,null,"en",null,null,null,null,[]]'
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论