He escrito un descargador de subprocesos múltiples pausable usando solicitudes y subprocesos, sin embargo, las descargas simplemente no pueden completarse después de reanudar, en pocas palabras, debido a las condiciones especiales de la red, las conexiones a menudo pueden morir durante las descargas que requieren actualizar las conexiones.
Puede ver el código aquí en mi pregunta anterior:
Observé que las descargas pueden ir más allá del 100% después de reanudar y no se detendrán (al menos no he visto que se detengan), los índices mmap se saldrán de los límites y muchos mensajes de error...
Finalmente me di cuenta de que esto se debe a que el fantasma de la solicitud anterior hace que el servidor envíe por error datos adicionales de la última conexión que no se descargaron.
Esta es mi solución:
s = requests.session() r = s.get( url, headers={'connection': 'close', 'range': 'bytes={0}-{1}'.format(start, end)}, stream=True) r.close() s.close() del r del sEn mis pruebas, descubrí que las solicitudes tienen dos atributos llamados sesión, un título, una minúscula, la minúscula es una función y el otro es un constructor de clase, ambos crean un objeto request.sessions.Session, ¿hay alguna diferencia entre ellos?
¿Y cómo puedo configurar keep-alive en False?
El método encontrado aquí ya no funcionará:
In [39]: s = requests.session() ...: s.config['keep_alive'] = False --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-39-497f569a91ba> in <module> 1 s = requests.session() ----> 2 s.config['keep_alive'] = False AttributeError: 'Session' object has no attribute 'config'Este método de aquí no arroja errores:
s = requests.session() s.keep_alive = FalsePero dudo seriamente que tenga algún efecto, solo agrega un nuevo booleano al objeto y no creo que el objeto lo maneje.
He visto un método de cierre en solicitudes.modelos.Respuesta, ¿tiene algún efecto en este caso o simplemente puedo cerrar la sesión?
Y, por último, con este método, ¿está garantizado que el servidor nunca enviará bytes adicionales de conexiones inactivas anteriores?
En general, con python, cuando hay algún tipo de 'controlador' que se supone que se cierra después del uso, envolver el uso with puede limitar el alcance de la cosa a un pequeño bloque de código.
ResponseData = None with requests.get( Url, headers=Headers) as ResponseObject: ResponseData = ResponseObject.text.encode('utf-8') ResponseData = ResponseData.decode("utf-8") #code down here does not have any idea what "ReponseObject" is. #For some reason python is able to kill it more reilably after `with`No estoy seguro de si esta es una respuesta canónica, pero podría serle útil. El fragmento funciona para mí, pero evito crear una sesión por completo. Este truco me ha funcionado para innumerables otras cosas que se suponía que debían cerrarse, pero no lo hicieron.
EDITAR: Seguimiento de la sesión: supongo que puedes duplicar with ver si funciona.
with requests.session() as s: with s.get(....) as r: #try stuff here