我正在使用非常简单的代码按地区查找关键字的数据。但每次我运行它时,它都会给我429错误,提示发出了太多请求,但实际上该请求是第一次发出,以前从未发出过。下面提到了我收到的错误。
引发异常。TooManyRequestsError.from_response(response) pytrends.exceptions.TooManyRequestsError:请求失败:Google 返回了代码 429 的响应
这是代码,我正在运行。
import pandas as pd
from pytrends.request import TrendReq
pytrend = TrendReq()
kw_list = ["Blockchain"]
pytrend.build_payload(kw_list, cat=0, timeframe='today 12-m', geo='', gprop='')
# Interest by Region
df = pytrend.interest_by_region()
df.head(10)
好吧,tprogrammer,我想我可能已经找到了你的答案,尽管我是从当前的 github 线程中得到的:发生异常:请求失败:Google 返回了代码为 429 的响应
///编辑(21.03.23): 用户“jesvinc”提供了一个更简洁的解决方案,将请求限制提升到之前的水平。 显然这与
GetGoogleCookie
方法有关,需要稍微改变一下。如果您进入 python 模块文件夹(我的位于 User\AppData\Roaming\Python\Python39\site-packages
),在 pytrends 中您将找到该文件 request.py
。打开它并将第 88 行中的“get”更改为“post”,如下所示:
return dict(filter(lambda i: i[0] == 'NID', requests.get(
到
return dict(filter(lambda i: i[0] == 'NID', requests.post(
经过此更改,甚至偶尔遗留的问题也消失了,并且它也再次开始与 VPN 配合使用。此修复很可能会以某种形式包含在下一个 pytrends 更新中,但在那之前,它可以正常工作。
我们通过增加尝试次数解决了这个问题。
import time
import pandas as pd
from pytrends.request import TrendReq
from pytrends.exceptions import TooManyRequestsError, ResponseError
from requests.exceptions import ReadTimeout
from unidecode import unidecode
import warnings
# Filtrar pero no ignorar las advertencias FutureWarning
warnings.simplefilter(action='ignore', category=FutureWarning)
# Configuración de Google Trends
pytrends = TrendReq(hl='es', tz=360, timeout=(10, 25)) # Aumentar el tiempo de espera
# Palabras clave a buscar por categoría
keywords_pain = ['Dengue', 'Gripe', 'Fiebre', 'Ibuprofeno', 'Paracetamol']
keywords_nutri = ['Complejo B', 'Sueño', 'Sistema inmune', 'Magnesio', 'Redoxitos']
keywords_derma = ['Piel seca', 'Heridas', 'Cicaplast', 'Bepanthol', 'Vitamina B5']
keywords_ped = ['Ibuprofeno para chicos', 'Paracetamol para chicos', 'Ibuprofeno 2 %', 'Gripe en chicos', 'Dolor en chicos']
# Lista de países a consultar
paises = ['AR', 'PY', 'CL', 'BO', 'UY']
# DataFrame vacío para almacenar todos los datos combinados
all_data_combined = pd.DataFrame()
def obtener_datos(pytrends, keywords, pais, categoria, intento=1, max_intentos=2000):
try:
# Construir la carga útil con los parámetros especificados
pytrends.build_payload(kw_list=keywords, timeframe='today 1-m', geo=pais) # Cambiado a 'today 1-m' para últimos 30 días
# Obtener datos de tendencias
trend_data = pytrends.interest_over_time()
if trend_data.empty:
print(f"No se encontraron datos de tendencias para {pais} en la categoría {categoria}")
return
# Eliminar la columna 'isPartial'
if 'isPartial' in trend_data.columns:
trend_data = trend_data.drop(columns=['isPartial'])
# Transformar el DataFrame de tendencias
trend_data.reset_index(inplace=True) # Resetear el índice para tener la fecha como columna
trend_data_melted = pd.melt(trend_data, id_vars=['date'], var_name='keyword', value_name='value')
# Añadir la columna del país
trend_data_melted['country'] = pais
# Obtener datos de interés por región
region_data = pytrends.interest_by_region(resolution='REGION', inc_low_vol=True, inc_geo_code=True)
if region_data.empty:
print(f"No se encontraron datos de interés por región para {pais} en la categoría {categoria}")
return
# Transformar el DataFrame de interés por región
region_data.reset_index(inplace=True) # Resetear el índice para tener la provincia como columna
region_data['geoName'] = region_data['geoName'].apply(unidecode) # Aplicar unidecode a los nombres de las regiones
region_data_melted = pd.melt(region_data, id_vars=['geoName'], var_name='keyword', value_name='region_value')
region_data_melted.rename(columns={'geoName': 'province'}, inplace=True)
# Añadir la columna del país
region_data_melted['country'] = pais
# Convertir region_value a numérico, ignorando errores
region_data_melted['region_value'] = pd.to_numeric(region_data_melted['region_value'], errors='coerce')
# Obtener la keyword con el valor más alto por provincia
idx = region_data_melted.groupby(['country', 'province'])['region_value'].idxmax()
top_keywords_per_province = region_data_melted.loc[idx, ['country', 'province', 'keyword']].rename(columns={'keyword': 'top_keyword'})
# Combinar los dos DataFrames
combined_data = trend_data_melted.merge(region_data_melted, on=['keyword', 'country'], how='left')
# Añadir la columna de la categoría
combined_data['category'] = categoria
# Añadir la keyword con el valor más alto por provincia
combined_data = combined_data.merge(top_keywords_per_province, on=['country', 'province'], how='left')
# Añadir los datos combinados al DataFrame global
global all_data_combined
all_data_combined = pd.concat([all_data_combined, combined_data], ignore_index=True)
print(f"Datos agregados correctamente para {pais} en la categoría {categoria}")
except TooManyRequestsError:
if intento <= max_intentos:
print(f"Error 429: Demasiadas solicitudes. Esperando antes de reintentar para {pais}... (Intento {intento}/{max_intentos})")
# time.sleep(2) # Esperar más tiempo con cada reintento
obtener_datos(pytrends, keywords, pais, categoria, intento + 1)
else:
print(f"Error 429: Demasiadas solicitudes. Superado el número máximo de intentos para {pais}.")
except ReadTimeout:
if intento <= max_intentos:
print(f"ReadTimeout: La solicitud para {pais} en la categoría {categoria} ha tardado demasiado. Reintentando... (Intento {intento}/{max_intentos})")
# time.sleep(2) # Esperar más tiempo con cada reintento
obtener_datos(pytrends, keywords, pais, categoria, intento + 1)
else:
print(f"ReadTimeout: Superado el número máximo de intentos para {pais} en la categoría {categoria}.")
except ResponseError as e:
print(f"ResponseError: {e}. Verifica los parámetros y vuelve a intentarlo.")
# Iterar sobre cada país y categoría
for pais in paises:
obtener_datos(pytrends, keywords_pain, pais, 'Pain')
time.sleep(1) # Esperar 30 segundos antes de la siguiente solicitud
obtener_datos(pytrends, keywords_nutri, pais, 'Nutri')
time.sleep(1)
obtener_datos(pytrends, keywords_derma, pais, 'Derma')
time.sleep(1)
obtener_datos(pytrends, keywords_ped, pais, 'Ped')
time.sleep(1) # Esperar 30 segundos antes de realizar la siguiente consulta para otro país
# Guardar el DataFrame combinado en un único archivo Excel
all_data_combined.to_excel('C:\\Users\\XXXXXXX\\OneDrive - XXXXX\\Desktop\\GoogleTrends.xlsx', index=False)
print("Datos guardados correctamente en GoogleTrends.xlsx")