繁体   English   中英

谷歌翻译 API id 阻止了太多请求的 IP 地址

[英]Google Translation API id blocking ip address for too many requests

我正在设置一个Django视图,它从 API 请求产品数据,使用BeautifulSoup解析它们,应用googletrans模块并将响应保存到我的 Postgresql 数据库中。

昨天一切正常,直到突然间,Google 一次阻止了对我 IP 地址的访问,因为请求太多了。

我刚刚打开我的 LTE 来更改我的 IP 地址并且它起作用了。

但是现在,为了确保这个 IP 地址不会再次发生这种情况,我需要找到一种方法来批量调用googletrans API 或任何其他可以防止我再次被阻止的解决方案。

这是我的观点:

from bs4 import BeautifulSoup
from googletrans import Translator
import requests
import json


def api_data(request):
    if request.GET.get('mybtn'):  # to improve, == 'something':
        resp_1 = requests.get(
            "https://www.headout.com/api/public/v1/product/listing/list-by/city?language=fr&cityCode=PARIS&limit=5000&currencyCode=CAD",
            headers={
                "Headout-Auth": HEADOUT_PRODUCTION_API_KEY
            })
        resp_1_data = resp_1.json()
        base_url_2 = "https://www.headout.com/api/public/v1/product/get/"

        translator = Translator()

        for item in resp_1_data['items']:
            print('translating item {}'.format(item['id']))
            # concat ID to the URL string
            url = '{}{}'.format(base_url_2, item['id'] + '?language=fr')

            # make the HTTP request
            resp_2 = requests.get(
                url,
                headers={
                    "Headout-Auth": HEADOUT_PRODUCTION_API_KEY
                })
            resp_2_data = resp_2.json()

            descriptiontxt = resp_2_data['contentListHtml'][0]['html'][0:2040] + ' ...'

            #Parsing work
            soup = BeautifulSoup(descriptiontxt, 'lxml')
            parsed = soup.find('p').text

            #Translation doesn't work
            translation = translator.translate(parsed, dest='fr')

            titlename = item['name']
            titlefr = translator.translate(titlename, dest='fr')

            destinationname = item['city']['name']
            destinationfr = translator.translate(destinationname, dest='fr')

            Product.objects.get_or_create(
                title=titlefr.text,
                destination=destinationfr.text,
                description=translation.text,
                link=item['canonicalUrl'],
                image=item['image']['url']
            )

    return render(request, "form.html")

如何批量调用谷歌翻译API? 或者有没有其他解决方案?

请帮忙。

编辑

基于@ddor254 我应该把: time.sleep time.sleep(2)放在哪里?

这是我想出来的,可以吗?

  Product.objects.get_or_create(
      title=titlefr.text,
      destination=destinationfr.text,
      description=translation.text,
      link=item['canonicalUrl'],
      image=item['image']['url']
  )time.sleep(2) #here

或者像这样:

resp_1 = requests.get(
            "https://www.headout.com/api/public/v1/product/listing/list-by/city?language=fr&cityCode=PARIS&limit=5000&currencyCode=CAD",
            headers={
                "Headout-Auth": HEADOUT_PRODUCTION_API_KEY
            }, time.sleep(2)) #here

只是想确保它是正确的方法,然后再冒这个新 IP 也被封锁的风险。

我建议你从 MDN 阅读这篇文章: https : //developer.mozilla.org/en-US/docs/Web/HTTP/Status/429

如果这是您得到的响应,请尝试查看响应对象中的标头Retry-After

因此,使用该标头的值添加睡眠或其他延迟方法可能会解决您的问题。

尝试在连续查询之间添加延迟(使用睡眠)并使用数字来查看哪些对您有用。 每对翻译后延迟 2 秒,每 10 对翻译后延迟 15 秒,对我来说效果很好。

由于许多并发请求,我也被阻止了。 通常在 500 个并发请求后总是被阻塞。 我所做的是在每 100 个并发请求后设置 60 秒的超时时间。 它可能看起来很长,但它确实有效。 您也可以通过 45 秒的超时来实现这一点,但我将其设置为 60 只是为了确保。

这是一个例子

class GoogleAPI():

    def __init__(self):
        self.limit_before_timeout = 100
        self.timeout = 60

    def translate(self, source):
        translation = translator.translate(source, dest="ar")
        translation = translation.__dict__['text']
        if translation != "" and translation is not None:
            return translation

    def process(self):
        i = 0
        print("initiation")
        for t in list_of_data:
            if i < self.limit_before_timeout:
                i += 1
                self.translate(t)
            else:
                i = 0
                print("100 words added")
                time.sleep(self.timeout)
        print("All done")

大约 450 个并发连接后,我的 IP 被阻止。 我正在使用 php for 循环来翻译我的文本数组。

因此,我更改了我的 IP 地址,并更改了每 x 秒后等待的代码。

我在 For 循环中的代码($i 是 for 循环中的值):

if ($i % 100 == 0 && $i!=0) {
    //wait 60 seconds every 100
    usleep(60000000);   // 60 seconds
    echo str_pad("XX--> WAITING 60 SECONDS<br>",4096);
}               
else 
if ($i % 10 == 0  && $i!=0) {
    //wait 15 seconds every 10
     usleep(15000000); // 15 seconds
     echo str_pad("XX--> WAITING 15 SECONDS<br>",4096);
}
else    
if ($i % 2 == 0  && $i!=0) {
    //wait 2 seconds every 2
     usleep(2000000); // 2 seconds
     echo str_pad("XX--> WAITING 2 SECONDS<br>",4096);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM