Urllib urlopen, разбивающийся на некоторых сайтах (например, StackApps api): возвращает результаты мусора

Я использую функцию urllib2 urlopen, чтобы попытаться получить результат JSON из apache StackOverflow.

Код, который я использую:

>>> import urllib2
>>> conn = urllib2.urlopen("http://api.stackoverflow.com/0.8/users/")
>>> conn.readline()

Результат, который я получаю:

'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\xed\xbd\x07`\x1cI\x96%&/m\xca{\x7fJ\...

Я новичок в urllib, но это не похоже на результат, который я должен получить. Я пробовал это в других местах, и я получаю то, что ожидаю (так же, как посещение адреса с помощью браузера дает мне: объект JSON).

Использование urlopen на других сайтах (например, http://google.com") отлично работает и дает мне фактический html. Я также попытался использовать urllib, и он дает тот же результат.

Я довольно застрял, даже не зная, где искать эту проблему. Любые идеи?

Ответ 1

Это почти похоже на то, что вы будете кормить, чтобы мариновать. Возможно, что-то в строке User-Agent или Accepts, которую отправляет urllib2, вызывает StackOverflow для отправки чего-то другого, кроме JSON.

Однозначное - посмотреть conn.headers.headers, чтобы увидеть, что говорит заголовок Content-Type.

И этот вопрос, Нечетный формат строки результата из вызова API, может иметь ваш ответ. В принципе, вам может понадобиться запустить ваш результат с помощью декомпрессора gzip.

Двойная проверка с помощью этого кода:

>>> req = urllib2.Request("http://api.stackoverflow.com/0.8/users/",
                          headers={'Accept-Encoding': 'gzip, identity'})
>>> conn = urllib2.urlopen(req)
>>> val = conn.read()
>>> conn.close()
>>> val[0:25]
'\x1f\x8b\x08\x00\x00\x00\x00\x00\x04\x00\xed\xbd\x07`\x1cI\x96%&/m\xca{\x7fJ'

Да, вы определенно получаете данные с кодировкой gzip.

Поскольку вы, похоже, получаете разные результаты на разных машинах с той же версией Python, и в целом похоже, что API urllib2 потребует от вас что-то особенное для запроса данных, закодированных gzip, я предполагаю, что у вас есть прозрачный прокси-сервера там где-то.

Я видел презентацию EFF на CodeCon в 2009 году. Они проводили сквозное тестирование соединений, чтобы обнаружить грязные трюки ISP различного рода. Одна из вещей, которые они обнаружили при этом тестировании, заключается в том, что удивительное количество маршрутизаторов NAT на уровне потребителей добавляет случайные заголовки HTTP или делает прозрачное проксирование. Возможно, в вашей сети есть часть оборудования, добавляющее или изменяющее заголовок Accept-Encoding, чтобы ваше соединение выглядело быстрее.