【问题标题】:Google Translation API id blocking ip address for too many requests谷歌翻译 API id 阻止了太多请求的 IP 地址
【发布时间】:2019-10-17 21:19:21
【问题描述】:

我正在设置一个 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(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 也被阻止的风险。

【问题讨论】:

    标签: python django python-requests batch-processing google-translation-api


    【解决方案1】:

    我的 IP 在大约 450 个并发连接后被阻止。我正在使用 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);
    }
    

    【讨论】:

      【解决方案2】:

      我也因为许多并发请求而被阻止。通常总是在 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")
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

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

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

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

          【讨论】:

          • 是的,这是我得到的 429 状态!
          • 您知道如何按照建议添加睡眠或其他延迟方法吗?我对 python 很陌生!
          • 在脚本顶部添加“导入时间”,然后在每次请求后添加time.sleep(2) 2 秒,您可以从响应中输入Retry-After 的值,但我认为现在你可以花 2 秒时间看看它是否能解决你的问题 - 如果是,请接受答案:)
          • 谢谢,我现在就试试这个。
          • 我刚刚编辑了这个问题,包括一个应该放置time.sleep(2) 的示例,你能告诉我它是否正确吗?
          猜你喜欢
          • 2015-01-30
          • 1970-01-01
          • 2015-11-10
          • 1970-01-01
          • 2018-02-19
          • 1970-01-01
          • 2017-09-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多