[Python] Hilo general

B

Buenas.

Me quiero hacer un pequeño programita en python que se encargue de hacer peticiones a una api y, si hay algún cambio, seguir con el programa.

Mi duda viene con el tema de las llamadas, ¿Cada cuánto he de hacer las peticiones? ¿Puedo dejar al bot en modo latente? No sé qué tengo que leer para solucionar esta duda.

La api en cuestión es esta.

Y he estado viendo hay que un rate limit por lo que entiendo que los tiros van por ahí... Serían simplemente peticiones GET

2 respuestas
Rivendel

#1621 la api te limita para que no haya spam, el link que has puesto es correcto depende de la funcion que llames hay distintos limites, tienes que timear tu codigo para que no sobrepase 1000 calls every 5 minutes como dicen los docs es 1 cada 0.3 secs, puede poner una por segundo o cada medio segundo si testear

Lolerpopler

#1621 La pregunta es, por que quieres llamar repetidamente a la API? es porque quieres spamearla o porque quieres monitorizar si hay algun cambio? Si es lo segundo preguntante, necesitas saber la nueva informacion en cuanto haya cambiado o puedes esperar 1 hora, 1 dia, 1 semana... Lo mas adecuado seria tener un cronjob que ejecute el script de python regularmente con la frecuencia que necesites (si es el segundo caso que he comentado, claro)

1 respuesta
B

#1623 Necesito que cuando haya un cambio el bot lo detecte automáticamente por lo que tiene que estar en constante monitoreo.

1 respuesta
eondev

#1624 pues metele 1 minuto de espera y au

1 respuesta
B

#1625 Ok, probaré, gracias a todos.

2 respuestas
eondev

#1626 supongo que preguntabas por si había algún método para escucha permanente o algo así, pero al ser REST lo más sencillo es que implementes tú el pooling, que no es más que un bucle en espera de X tiempo para volver a consultar.

Esa espera es lo que consideres tú necesario, si al usuario le es necesario que esté al segundo o si por lo contrario 30s/1m da la misma sensación de inmediatez en novedades.

Si fuese una fuente de datos interna, o si usases algún componente de observar cambios, internamente se hace lo mismo pero con tiempos de ms o menos. Al final la declaración imperativa de esperar consultar y repetir se hace sí o sí.

Unrack

#1626 Si no quieres salirte de python puedes utilizar https://schedule.readthedocs.io/en/stable/
La única limitación sería que no trabaja a subsegundo pero es muy simple de usar.

B

A mi entender, lo que necesitas debería de ofrecertelo la api a la que estás tirando consultas.... es mejor para ti, y mejor para ellos. ¿Has mirado si la API no te ofrece eso? EN plan... decirle: Envíame a pepe.com/soy/el/mejor cuando suceda un evento. Y tu servidor al escuchar eso... tiraría la petición completa contra el servidor.

CiudadanoEj

Buenas,

Estoy intentando hacer un bot que me apueste en bet365 con webscrapping(selenium) pero a la hora de hacer el login automatico me dice que no son correctos y si los entro manualmente me deja y leyendo/buscando he visto que tienen alguna cosa de antiwebscrapping y no consigo pasarlo a ver si podeis echarme una mano porque lo que encuentro por internet no funciona

A dia de hoy tengo esto:

spoiler
1 respuesta
Lolerpopler

#1630 El problema dudo que este en el codigo, habria que mirar la web, mi primera intuicion: honeypot. Algun campo en la web que esta puesto para cazar bots y que no es visible para un humano.
Verifica que las ids y estes en la parte correcta del arbol html y no en algun campo hecho para pillar bots. Al fin y al cabo solo estas buscando estos dos campos

    # username = Bet365driver.find_element(By.CLASS_NAME, "lms-StandardLogin_Username")
    # password = Bet365driver.find_element(By.CLASS_NAME, "lms-StandardLogin_Password ")

No estas verificando que sean unicos en la web o que sean los que corresponden al formulario que tu ves como usuario

2 1 respuesta
CiudadanoEj

#1631 pues no habia pensado en eso le echare un ojo.

Gracias

8 días después
hda

Tengo que compartirlo, jaja.

Acabo de pasar un proceso de \~24 minutos a 614 ms ± 7.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) XDXDXD Qué bien sienta esta mierda.

Un 2345× de speedup wiii

2 1 respuesta
Rivendel

#1633 mas detalle, pedazo optimizacion

1 respuesta
hda

#1634 Pues te creas o no había escrito todos los sniplets aquí y pasé de publicarlo jaja

Estoy trabajando con strings y pandas. Tengo un campo con una o más palabras. Debo seleccionar del dataframe tan solo las filas que en este campo tengan al menos una palabra entre una lista de 5000 palabras. Así que programé lo típico: para cada fila un loop any(word in kw5000 for word in kwCampo). Luego se me ocurrió que quizás era más conveniente trabajar con sets.

  1. Hice set la lista de las 5000 palabras. set_kw5000 = set(kw5000)
  2. Hice set al split de las palabras en cada fila
    1. pd["campolist"] = pd.campo.str.split()
    2. pd["camposet"] = pd.campolist.map(set)

Y luego trabajé con los sets, básicamente comparo si el tamaño del set de palabras del campo es mayor que el tamaño de la resta entre el set de palabras del campo menos set de 5k palabras.

df["camposet"].progress_apply(lambda x, meds=set_kw5000 : len(x) > len(x-meds))

Probablemente el mayor speedup de mi carrera, jaja. Sí he traído cosas de dos semanas (algoritmo de antes de entrar en este puesto) a unas 6 horas, 56× de speedup. Pero nada como esto que acabo de hacer.

2 1 respuesta
Slowbro

#1635 diccionarios y sets, la auténtica gloria.

Casi merece mas la pena pensar 30 mins en como resolver tu problema con eso que ponerse a picar directamente. Pura salud.

3
8 días después
gonya707

Una duda que me esta sacando de quicio con instanciancion de clases. Tengo una clase Foo y un funcion para llenar una lista de Foo y otra para mostrarla, hasta aqui todo bien

class Foo:
    def __init__(self):
        self.values = randint(1, 100)

def add_one_foo_to_list():
    new_foo = Foo()
    foo_list.append(new_foo)

def print_foo_list_content():
    for foo in foo_list:
        print(foo.values)
    print("\n")

foo_list = []

add_one_foo_to_list()
print_foo_list_content()

add_one_foo_to_list()
print_foo_list_content()

add_one_foo_to_list()
print_foo_list_content()
Resultado consola

Ahora hago lo mismo con otra clase NumberTile que en vez de almacenar un numero aleatorio tiene una lista tambien aleatoria con colores. Literalmente cambio solo el Foo() con NumberTile() en el codigo anterior y siempre pasa esto:

Resultado consola

Es como si cuando hago append a new_foo se guardase una referencia, y al sobreescribir la variable new_foo todas las referencias ya guardadas en la lista se cambian, y al final siempre tengo una lista de 3 elementos iguales.

Ya he probado a guardar en la lista con copy/deepcopy y el resultado es el mismo, que estoy haciendo mal?

2 respuestas
Vashealer

#1637 Puedes poner el código de NumberTile? :thinking:

1 respuesta
gonya707

#1638 claro

TILE_COLORS = ['🟩', '🟨', '🟦']


class NumberTile:
    values = ['', '', '', '']

def __init__(self):
    for index in range(len(self.values)):
        self.values[index] = choice(TILE_COLORS)
1 respuesta
Vashealer

#1639 Creo que has puesto values como class attribute en vez de instancia

btw, hacer

range(len())

es un poco extraño, si un caso se puede usar

enumerate()

Por otra parte las clases son raras, para las values del NumberTile es mejor usar un list comprehension, cuando vayas a crear estructuras

 [choice(TILE_COLORS) for i in range(4) 

en vez de 4 pon la lista que necesitas o el tamaño de los tiles, eso podría ser una propiedad de la misma clase

1 respuesta
gonya707

#1640 fuck, eso era xd, pensaba que iba todo en el mismo saco, tengo que repasar como van las clases de python, gracias

la nueva NumberTile

class NumberTile:
    def __init__(self):
        self.values = [choice(TILE_COLORS) for n in range(4)]
1 1 respuesta
Vashealer

#1641 vale, veo que has puesto lo mismo xd! tardé en editar

1
PaCoX

¿Cómo llamas a una serpiente que cuenta chistes? Monty Pitón

ha
	ha
		ha
CaNaRy_r00lz

#1637 Una pregunta sobre tu codigo pones esto al fina:

add_one_foo_to_list()
print_foo_list_content()

add_one_foo_to_list()
print_foo_list_content()

add_one_foo_to_list()
print_foo_list_content()

Eso es pk quieres llamar 3 veces distintas al add_one_foo_to_list ya que al principio en la clase tienes un randint(1,100) y ver que 3 resultados distintos te da?

1 respuesta
gonya707

#1644 si eso es, es para añadir tres elementos a la lista e imprimirlos cada vez para ver como se rellena. Con numeros salía bien pero con los colores solo replicaba el último resultado en cada entrada

1 respuesta
CaNaRy_r00lz

#1645 Gracias, queria saber si habia entendido bien lo que pretendias xD parece que al final va entrando algo xD

7 días después
1mP

Edit: Me voy a pensar d nuevo las cosas.

1 respuesta
newfag

#1647 https://www.w3schools.com/python/python_operators.asp

1
B

Alguien podría decirme como hacerlo para que el password generado contenga mínimo 1 letra, 1 numero y 1 símbolo? A veces me genera passwords que no contienen todas las variables pero no se como cojones hacerlo para que lo incluya todo.

Código en cuestión:

spoiler

PD: Llevo literalmente 3 días aprendiendo Python, cosas simples por favor.

3 respuestas
KooPad

#1649 Podrías siempre al inicio del programa seleccionar una letra, número y símbolo. Después simplemente coge "length-3" y concatenarlo con el string anterior. Si lo haces así luego de formar el string deberías hacer una permutación de nuevo para que no tengas siempre el mismo orden de los primeros chars.

2 respuestas