Urllib2 не получает весь HTTP-ответ
Я недоумеваю, почему я не могу загрузить все содержимое некоторых ответов JSON из FriendFeed, используя urllib2.
>>> import urllib2
>>> stream = urllib2.urlopen('http://friendfeed.com/api/room/the-life-scientists/profile?format=json')
>>> stream.headers['content-length']
'168928'
>>> data = stream.read()
>>> len(data)
61058
>>> # We can see here that I did not retrieve the full JSON
... # given that the stream doesn't end with a closing }
...
>>> data[-40:]
'ce2-003048343a40","name":"Vincent Racani'
Как получить полный ответ с помощью urllib2?
Ответы
Ответ 1
Лучший способ получить все данные:
fp = urllib2.urlopen("http://www.example.com/index.cfm")
response = ""
while 1:
data = fp.read()
if not data: # This might need to be if data == "": -- can't remember
break
response += data
print response
Причина в том, что .read()
не гарантированно возвращает весь ответ, учитывая природу сокетов. Я думал, что это обсуждалось в документации (возможно, urllib
), но я не могу ее найти.
Ответ 2
Используйте tcpdump (или что-то в этом роде) для мониторинга реальных сетевых взаимодействий - тогда вы можете проанализировать, почему сайт нарушен для некоторых клиентских библиотек. Убедитесь, что вы повторяете несколько раз, создавая сценарий теста, чтобы убедиться, что проблема последовательна:
import urllib2
url = 'http://friendfeed.com/api/room/friendfeed-feedback/profile?format=json'
stream = urllib2.urlopen(url)
expected = int(stream.headers['content-length'])
data = stream.read()
datalen = len(data)
print expected, datalen, expected == datalen
Сайт работает последовательно для меня, поэтому я не могу привести примеры поиска сбоев:)
Ответ 3
Продолжайте вызывать stream.read(), пока это не закончится...
while data = stream.read() :
... do stuff with data
Ответ 4
readlines()
также работает