簡體   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