J'utilise la bibliothèque de requêtes pour obtenir de nombreuses pages Web de quelque part. Il est le code pertinent:

response = requests.Session()
retries = Retry(total=5, backoff_factor=.1)
response.mount('http://', HTTPAdapter(max_retries=retries))
response = response.get(url)

Après un certain temps, il se bloque / se fige (jamais sur la même page Web) tout en obtenant la page. Voici le retraçage lorsque je l'interromps:

File "/Users/Student/Hockey/Scrape/html_pbp.py", line 21, in get_pbp
  response = r.read().decode('utf-8')
File "/anaconda/lib/python3.6/http/client.py", line 456, in read
  return self._readall_chunked()
File "/anaconda/lib/python3.6/http/client.py", line 566, in _readall_chunked
  value.append(self._safe_read(chunk_left))
File "/anaconda/lib/python3.6/http/client.py", line 612, in _safe_read
  chunk = self.fp.read(min(amt, MAXAMOUNT))
File "/anaconda/lib/python3.6/socket.py", line 586, in readinto
  return self._sock.recv_into(b)
KeyboardInterrupt

Quelqu'un sait-il ce qui pourrait en être la cause? Ou (plus important encore) est-ce que quelqu'un connaît un moyen de l'arrêter si cela prend plus d'un certain temps pour que je puisse réessayer?

12
Hobbit36 23 juil. 2017 à 18:48

2 réponses

Meilleure réponse

Il semble que la définition d'un timeout (lecture) pourrait vous aider.

Quelque chose dans le sens de:

response = response.get(url, timeout=5)

(Cela définira le délai de connexion et de lecture à 5 secondes.)

Dans requests, malheureusement, ni les délais d'expiration de connect ni de lecture ne sont définis par défaut, même si les docs dit qu'il est bon de le définir:

La plupart des demandes adressées aux serveurs externes doivent être associées à un délai d’attente , au cas où le serveur ne répondrait pas dans les délais. Par défaut, les demandes n'expirent pas sauf si une valeur de délai est définie explicitement. Sans délai, votre code peut se bloquer pendant plusieurs minutes ou plus.

Pour être complet, le délai de connexion est le nombre de secondes que requests attendra que votre client établisse une connexion à une machine distante, et le délai de lecture est le nombre de secondes que le client attendra entre les octets envoyés par le serveur.

16
randomir 23 juil. 2017 à 16:02

Pour définir le délai d'expiration globalement au lieu de le spécifier dans chaque requête:


from requests.adapters import TimeoutSauce

REQUESTS_TIMEOUT_SECONDS = float(os.getenv("REQUESTS_TIMEOUT_SECONDS", 5))

class CustomTimeout(TimeoutSauce):
    def __init__(self, *args, **kwargs):
        if kwargs["connect"] is None:
            kwargs["connect"] = REQUESTS_TIMEOUT_SECONDS
        if kwargs["read"] is None:
            kwargs["read"] = REQUESTS_TIMEOUT_SECONDS
        super().__init__(*args, **kwargs)


# Set it globally, instead of specifying ``timeout=..`` kwarg on each call.
requests.adapters.TimeoutSauce = CustomTimeout


sess = requests.Session()
sess.get(...)
sess.post(...)
0
Danila Vershinin 3 oct. 2019 à 19:19