Mantener un flujo de ruido durante mucho tiempo

Estoy ejecutando un python script que se supone que escuche tuits con un '@' específico (y luego ejecute algún código). Mi código está casi funcionando 100% correctamente pero todavía tengo un problema: mi programa deja de funcionar aleatoriamente por "ninguna razón". Aquí está el error:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/http/client.py", line 551, in _get_chunk_left
    chunk_left = self._read_next_chunk_size()
  File "/usr/local/lib/python3.8/http/client.py", line 518, in _read_next_chunk_size
    return int(line, 16)
ValueError: invalid literal for int() with base 16: b''

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/http/client.py", line 583, in _readinto_chunked
    chunk_left = self._get_chunk_left()
  File "/usr/local/lib/python3.8/http/client.py", line 553, in _get_chunk_left
    raise IncompleteRead(b'')
http.client.IncompleteRead: IncompleteRead(0 bytes read)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/urllib3/response.py", line 436, in _error_catcher
    yield
  File "/usr/local/lib/python3.8/site-packages/urllib3/response.py", line 518, in read
    data = self._fp.read(amt) if not fp_closed else b""
  File "/usr/local/lib/python3.8/http/client.py", line 454, in read
    n = self.readinto(b)
  File "/usr/local/lib/python3.8/http/client.py", line 488, in readinto
    return self._readinto_chunked(b)
  File "/usr/local/lib/python3.8/http/client.py", line 599, in _readinto_chunked
    raise IncompleteRead(bytes(b[0:total_bytes]))
http.client.IncompleteRead: IncompleteRead(292 bytes read)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 133, in 
    myStream.filter(track=['@DownDropship'])
  File "/usr/local/lib/python3.8/site-packages/tweepy/streaming.py", line 474, in filter
    self._start(is_async)
  File "/usr/local/lib/python3.8/site-packages/tweepy/streaming.py", line 389, in _start
    self._run()
  File "/usr/local/lib/python3.8/site-packages/tweepy/streaming.py", line 320, in _run
    six.reraise(*exc_info)
  File "/usr/local/lib/python3.8/site-packages/six.py", line 703, in reraise
    raise value
  File "/usr/local/lib/python3.8/site-packages/tweepy/streaming.py", line 289, in _run
    self._read_loop(resp)
  File "/usr/local/lib/python3.8/site-packages/tweepy/streaming.py", line 339, in _read_loop
    line = buf.read_line()
  File "/usr/local/lib/python3.8/site-packages/tweepy/streaming.py", line 200, in read_line
    self._buffer += self._stream.read(self._chunk_size)
  File "/usr/local/lib/python3.8/site-packages/urllib3/response.py", line 540, in read
    raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
  File "/usr/local/lib/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/usr/local/lib/python3.8/site-packages/urllib3/response.py", line 454, in _error_catcher
    raise ProtocolError("Connection broken: %r" % e, e)
urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(292 bytes read)', IncompleteRead(292 bytes read))

Aquí está un pedazo de mi código:

    from tweepy import StreamListener
    from retrying import retry
    import tweepy

    @retry
    class MyStreamListener(StreamListener):


        @retry
        def on_status(self, status):
            do something ...
            except Exception as e:
                pass

    myStreamListener = MyStreamListener()
    myStream = tweepy.Stream(auth=twitter_handler.api.auth, listener=myStreamListener)
    myStream.filter(track=['@Something'])

Encontré estos "@retry" Aquí. pero aparentemente, no funciona correctamente.

Gracias por tu ayuda

Pregunta hecha hace 3 años, 4 meses, 13 días - Por codecanvas


2 Respuestas:

  • El error que estás experimentando parece deberse a una conexión interrumpida con la API de Twitter al mantener el flujo de datos de los tweets. Para solucionar este problema, considera implementar un mecanismo de reintento y manejo de excepciones más robusto en tu código. Aquí te dejo algunas sugerencias:

    • Manejo de Excepciones:
    Asegúrate de manejar de manera adecuada las excepciones que puedan ocurrir durante la transmisión de tweets. En tu función on_status, captura y gestiona las excepciones de manera apropiada en lugar de simplemente pasarlas con except Exception as e: pass.

    • Mecanismo de Reintentos:
    El uso de @retry de la biblioteca retrying es una buena idea, pero asegúrate de configurar los parámetros correctos para los reintentos, por ejemplo, estableciendo un intervalo de tiempo entre reintentos y un número máximo de intentos.

    • Control de Errores de Conexión:
    Considera manejar específicamente los errores de conexión con la API de Twitter, como IncompleteRead o ProtocolError, para poder realizar las acciones adecuadas cuando ocurran.

    Aquí tienes un ejemplo modificado de cómo podrías mejorar tu código:

    python
    from tweepy import StreamListener
    from retrying import retry
    import tweepy
    import urllib3.exceptions
    
    @retry(wait_fixed=2000, stop_max_attempt_number=5)
    class MyStreamListener(StreamListener):
    
        def on_status(self, status):
            try:
                

    Código para procesar el tweet

    pass except Exception as e: print(f"Error al procesar tweet: {e}") myStreamListener = MyStreamListener() myStream = tweepy.Stream(auth=twitter_handler.api.auth, listener=myStreamListener) try: myStream.filter(track=['@Something']) except (urllib3.exceptions.ProtocolError, http.client.IncompleteRead) as e:

    Manejar errores de conexión con la API de Twitter

    print(f"Error de conexión con la API de Twitter: {e}")

    Recuerda ajustar los parámetros de reintento (wait_fixed, stop_max_attempt_number, etc.) de acuerdo a tus necesidades y a la tasa de uso de la API de Twitter. Además, asegúrate de tener correctamente configuradas tus credenciales de autenticación con la API. Espero que estas sugerencias te ayuden a resolver el problema de conexión interrumpida en tu aplicación.

    Respondida el Dec 19, 2020 a las 00:17 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Analicemos el error y el código para identificar el problema y encontrar una solución:

    Error:

    El error se produce porque el flujo de Twitter devuelve una respuesta incompleta o rota. Esto puede deberse a varios factores, como problemas de red, problemas con el servidor de Twitter o problemas con el código de escucha.

    Código:

    El código utiliza la biblioteca retrying para manejar excepciones y reintentar operaciones fallidas. Sin embargo, en este caso, el código solo reintenta las funciones on_status y on_error dentro del oyente, pero no la operación de filtrado general.

    Solución:

    Para resolver este problema, debemos manejar las excepciones y reintentar toda la operación de filtrado, incluyendo la conexión a Twitter y la escucha de los tweets.

    Aquí tienes el código actualizado:

    python
    import time
    from tweepy import StreamListener
    from retrying import retry
    import tweepy
    
    class MyStreamListener(StreamListener):
        def on_status(self, status):
            try:
                

    Hacer algo...

    except Exception as e: pass def on_error(self, status): print(status) return True

    Mantener la conexión abierta

    @retry(wait_fixed=1000, stop_max_attempt_number=None) def stream_tweets():

    Crea un oyente y un flujo

    myStreamListener = MyStreamListener() myStream = tweepy.Stream(auth=twitter_handler.api.auth, listener=myStreamListener)

    Filtra los tweets

    try: myStream.filter(track=['@Something']) except Exception as e: print(e)

    Reconecta y reintenta

    stream_tweets()

    Inicia el flujo

    stream_tweets()

    Cambios:

    Hemos movido la decoración @retry a la función stream_tweets para reintentar toda la operación de filtrado. Añadimos un manejador on_error al oyente para imprimir el error y mantener la conexión abierta. Cambiamos el argumento stop_max_attempt_number=None para reintentar indefinidamente hasta que la operación tenga éxito. Colocamos un tiempo de espera de 1000 ms (1 segundo) entre reintentos para evitar sobrecargar el servidor de Twitter.

    Con estos cambios, el programa intentará reconectarse y reanudar el flujo automáticamente si se produce un error o una respuesta incompleta. Esto debería ayudar a mantener un flujo de ruido estable.

    Respondida el Dec 19, 2020 a las 00:26 - por Gemini

    Votos positivos: 0 | Votos negativos: 0