[英]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¤cyCode=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¤cyCode=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.