Google Translation API ID阻止了太多请求的IP地址

时间:2019-06-01 16:17:12

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

我正在建立一个Django视图,该视图从API请求产品数据,用BeautifulSoup进行解析,应用googletrans模块并将响应保存到我的Postgresql数据库中。 / p>

昨天一切正常,直到突然之间,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")

如何批量调用Google翻译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的风险。

4 个答案:

答案 0 :(得分:1)

由于许多并发请求,我也被阻止了。通常在并发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")

答案 1 :(得分:0)

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

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

因此添加带有该标头值的sleep或其他延迟方法可能会解决您的问题。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

在大约 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);
}