Уведомления

Группа в Telegram: @pythonsu

#1 Май 16, 2014 11:16:32

Andys
От:
Зарегистрирован: 2010-09-09
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Прерывание HTTPResponse.read() (http.client, python3)

Добрый день,
возникла необходимость поставить таймаут на чтение данных через HTTPConnection, посоветуйте как

Проблема в чем - не уверен, что это хороший метод, может есть какое-то другое решение?
Написал для себя скрипт скачки большого кол-ва страничек, бывает что какой-то из потоков подвисает намертво из-за потери связи с сервером, и никакие таймауты сокетов не работают…
После поиска в инете, заранее несколько замечаний:
1. Писать свой собственный модуль на основе сокетов я не осилю
2. Требуется прервать именно работающий read() - связь установлена, данные идут, питон не получает ни ошибки, ни конца потока, и тут мы хотим все это дело прервать сиюмоментно, не дожидаясь ни единого байта (т.е. даже read(блоками) не подходит)
3. Использую HTTPConnection для Keep-Alive (в примере заголовки убраны для меньшего объема)

Для тестов на веб-сервере сделал искуственно замедленный скрипт (страничка выдается 20 сек) -

<?php
for ($a=1;$a<=20;$a++) {
echo($a."<br>");
sleep(1);
flush();
}
?>

Питоновский скрипт пытается её скачать, если за 2 сек (взято от балды для быстроты тестов) страничка не скачивается - пытается повторить сначала, по истечению 5 попыток отваливается.
server = "localhost"
url = "http://localhost/delay/gen20.php"
def timeout(sock):
	logger.info("Timeout, trying to reconnect")
	sock.close()
def do_read():
	conn = http.client.HTTPConnection(server,timeout=5)
	logger.debug("HTTP conn created")
	for errcount in range(5):
		conn.connect()
		logger.debug(url + " - start fetch. Try %d of 5" % (errcount+1))
		try: 
			conn.request("GET",url)
			resp = conn.getresponse()
			t = Timer(2,timeout,[conn.sock])
			t.start()
			data = resp.read()
			print(data)
			t.cancel()	
			break
		except socket.timeout:
			resp.close()
			del resp
			conn.close()
			continue



Отредактировано Andys (Май 16, 2014 11:43:06)

Офлайн

#2 Май 16, 2014 12:20:16

GreyZmeem
От: Киев
Зарегистрирован: 2013-12-03
Сообщения: 147
Репутация: +  34  -
Профиль   Отправить e-mail  

Прерывание HTTPResponse.read() (http.client, python3)

Посмотрите в сторону requests.
При запросе там можно указать параметр timeout

<?php
$timeout = intval($_GET['timeout']);

echo("timeout: ".$timeout."<br/>\n");
for ($a=1;$a<=$timeout;$a++) {
echo($a."<br>\n");
sleep(1);
flush();
}
?>
import requests
 
url = 'http://example.com/test.php?timeout=5'
 
try:
    r = requests.get(url, timeout=10)
    print 'Data recieved'
except requests.exceptions.Timeout as e:
    print 'Got exception: {}'.format(e)
 
try:
    r = requests.get(url, timeout=2)
    print 'Data recieved'
except requests.exceptions.Timeout as e:
    print 'Got exception: {}'.format(e)
Вывод:
Data recieved
Got exception: HTTPConnectionPool(host='example.com', port=80): Read timed out. (read timeout=2)

Отредактировано GreyZmeem (Май 16, 2014 12:24:50)

Офлайн

#3 Май 25, 2014 21:05:09

Andys
От:
Зарегистрирован: 2010-09-09
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Прерывание HTTPResponse.read() (http.client, python3)

Спасибо :)
Попробую с ним поработать, имо это будет проще чем отлавливать баги в моем скачивальщике.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version