无法通过IP访问Google翻译API。

huangapple go评论59阅读模式
英文:

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&#39;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 = &#39;142.250.1.90&#39;

HOST = &#39;translate.googleapis.com&#39;
URL_FORMAT = &#39;https://{}/translate_a/single?client=gtx&amp;sl=en&amp;tl=fr&amp;q=a&#39;

def _build_request(ip):
    url = URL_FORMAT.format(ip)
    request = Request(url)
    request.add_header(&#39;Host&#39;, HOST)
    return request

urlopen(_build_request(ip), timeout=2.5, context=ssl._create_unverified_context()).close()

But I got this error:

urllib.error.URLError: &lt;urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)&gt;

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 = &quot;142.250.1.90&quot;

HOST = &quot;translate.googleapis.com&quot;
URL_FORMAT = &quot;https://{}/translate_a/single?client=gtx&amp;sl=en&amp;tl=fr&amp;q=a&quot;


def _build_request(ip):
    url = URL_FORMAT.format(ip)
    request = Request(url)
    request.add_header(&quot;Host&quot;, HOST)
    return request


def patch_context(ctx, server_hostname):
    old_wrap_socket = ctx.wrap_socket

    def new_wrap_socket(socket, **kwargs):
        kwargs[&quot;server_hostname&quot;] = 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&#39;[null,null,&quot;en&quot;,null,null,null,null,[]]&#39;

huangapple
  • 本文由 发表于 2023年5月13日 18:02:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76242154.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定