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