Скрипт Python не будет читать () после urlopen с сервера localhost gae dev - Сброс соединения по пиру - PullRequest
2 голосов
/ 11 января 2012

Итак, я запускаю сервер разработки Google App Engine (Java) на localhost. Я пытаюсь получить URL с помощью Python 2.7 urllib.urlopen. Первоначальное извлечение работает, но затем, когда я пытаюсь вызвать read () или readlines (), я получаю:

Traceback (most recent call last):
   File "./getMap.py", line 6, in <module>
    lst = f.readlines()
   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 513, in readlines
    line = self.readline()
   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 445, in readline
    data = self._sock.recv(self._rbufsize)
   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 552, in read
    s = self.fp.read(amt)
   File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 378, in read
    data = self._sock.recv(left) 
socket.error: [Errno 54] Connection reset by peer

Браузер работает, wget работает. Проблема возникает как с urllib, так и с urllib2. Вот код:

import urllib2

f = urllib2.urlopen("http://localhost:8080/default.jsp")
lst = f.readlines()

for a in lst:
    print a

Странно, я могу распечатать первую строку файла, используя readline () - я просто не могу получить файл целом . У меня возникает ощущение, что, возможно, Python «лениво» не запрашивает все содержимое URL, пока я не запрошу его через readlines (), и к тому времени сервер разработки движка приложения чрезмерно закрыл соединение. Но я могу быть совершенно неправ в этом.

Я пытался исследовать эту проблему, но я не видел ничего подходящего. В большинстве обращений к Google я вижу случайные, периодически возникающие проблемы с синхронизацией (это не проблема прерывистого режима, это надежно) или проблемы с прокси / брандмауэром (ничего подобного здесь не происходит).

Предполагая, что моя теория верна - есть ли способ заставить urlopen сразу получить весь ответ, как это делают wget и браузер? Или есть способ сказать серверу разработки GAE для охлаждения и не закрывать соединение так быстро? Я бы не стал погружаться в низкоуровневые сокеты Python, если бы мне не пришлось.

спасибо

p.s. пояснение: скрипт python просто запускается из командной строки и пытается установить соединение с сервером разработки GAE, который работает на том же компьютере. Я НЕ пытаюсь подключиться к серверу разработчиков GAE от себя или чего-то странного, сервер GAE работает на Java, а не на Python. На самом деле я пытаюсь сделать следующее: в моем веб-приложении GAE есть несколько веб-сервисов, и я пишу пакетный скрипт для получения / публикации этих веб-сервисов, чтобы при необходимости перезагрузить / очистить хранилище данных (пример : данные повреждены) Я могу использовать этот скрипт на python для резервного копирования данных, затем стереть хранилище данных, а затем снова использовать скрипт для загрузки этих данных обратно.

ОБНОВЛЕНИЕ: поэтому я попробовал еще несколько тестов. Python без проблем читает любой HTML-файл, обслуживаемый сервером разработки GAE. Однако любой JSP, даже самый простой JSP "hello world", не может прочитать с той же ошибкой "сброс соединения по одноранговой сети". Я постараюсь обновить версию GAE SDK до версии 1.6.1, я должен сделать это в любом случае, а может быть, и сейчас. Надеюсь, это исправит это.

Ответы [ 2 ]

1 голос
/ 12 января 2012

Хотя я не вижу ничего плохого в вашем коде Python и не знаю, что может быть не так с вашей установкой Java GAE, я вместо этого предлагаю другой подход к проблеме.

Вы упоминаете, что в основном хотите отправитьGET / POST запросы к вашему серверу и сохранение / последующее чтение содержимого, и такие инструменты командной строки, как wget, работают.Я предлагаю вам использовать bash-скрипт, а также curl и python для случаев, когда вам нужно более сложное редактирование текста.

curl http://localhost:8080/default.jsp > default.bak
... wipe db ...
data = $(cat default.bak)
curl -X "POST" -d "backup=$data" http://localhost:8080/default_restore.jsp

Если вам нужно отредактировать данные перед отправкой, вы можете использовать python для чтения из default.bak или передачи его в stdin

data = $(cat default.bak)
python your_script.py $data

curl http://localhost:8080/default.jsp | python yourscript.py > default.bak
0 голосов
/ 18 марта 2015

Очевидно, я немного опоздал на вечеринку, но у меня была точно такая же проблема, и я решил ее, заменив urllib на httplib:

import httplib
conn = httplib.HTTPConnection('localhost:8080')

# get the current image and save to file
url = 'default.jsp'
conn.request("GET", url)
response = conn.getresponse()
if response.status == 404:
    return None
img_file = open("out.jpg",'wb')
img_file.write(response.read())
img_file.close()
response.close()
conn.close()

Не знаю, почему это работает, я могутолько предположим, что httplib ведет себя немного лучше, чем urllib

...