Получить заголовок с помощью Python и преобразовать в JSON (запросы — urllib2 — json)

Я пытаюсь получить заголовок с веб-сайта, закодировать его в JSON, чтобы записать в файл. Я пробовал два разных способа без успеха.

ПЕРВЫЙ с urllib2 и json

import urllib2
import json
host = ("https://www.python.org/")
header = urllib2.urlopen(host).info()
json_header = json.dumps(header)
print json_header

таким образом я получаю ошибку:

TypeError: нельзя сериализовать JSON

Поэтому я пытаюсь обойти эту проблему, преобразуя объект в строку -> json_header = str(header) Таким образом, я могу json_header = json.dumps(header), но вывод получается странным:

"Дата: среда, 02 июля 2014 г., 13:33:37 по Гринвичу\r\nСервер: nginx\r\nContent-Type: text/html; charset=utf-8\r\nX-Frame-Options: SAMEORIGIN\r\nContent -Длина: 45682\r\nAccept-Диапазоны: байты\r\nVia: 1.1 лак\r\nВозраст: 1263\r\nX-Served-By: cache-fra1220-FRA\r\nX-Cache: HIT\r\ nX-Cache-Hits: 2\r\nVary: Cookie\r\nStrict-Transport-Security: max-age=63072000; includeSubDomains\r\nConnection: close\r\n"

ВТОРОЙ с запросами

import requests
r = requests.get(“https://www.python.org/”)
rh = r.headers
print rh

{'content-length': '45682', 'через': '1.1 лак', 'x-cache': 'HIT', 'accept-ranges': 'bytes', 'strict-transport-security': 'max -возраст=63072000; includeSubDomains», «различные»: «Cookie», «сервер»: «nginx», «x-served-by»: «cache-fra1226-FRA», «x-cache-hits»: «14», «дата» : 'Ср, 02 июля 2014 г., 13:39:33 по Гринвичу', 'x-frame-options': 'SAMEORIGIN', 'content-type': 'text/html; кодировка=utf-8', 'возраст': '1619'}

Таким образом, вывод больше похож на JSON, но все же не в порядке (см. « » вместо « « и другие вещи, такие как = и ;). Очевидно, есть что-то (или многое), что я делаю не так. Я пытался читать документацию модулей, но не могу понять, как решить эту проблему. Спасибо за помощь.


person The One Electronic    schedule 02.07.2014    source источник


Ответы (4)


Существует несколько способов кодирования заголовков как JSON, но моей первой мыслью было бы преобразовать атрибут headers в фактический словарь, а не обращаться к нему как requests.structures.CaseInsensitiveDict.

import requests, json
r = requests.get("https://www.python.org/")
rh = json.dumps(r.headers.__dict__['_store'])
print rh

{'content-length': ('content-length', '45474'), 'через': ('через', '1.1 лак'), 'x-cache': ('x-cache', 'HIT' ), 'accept-ranges': ('accept-ranges', 'bytes'), 'strict-transport-security': ('strict-transport-security', 'max-age=63072000; includeSubDomains'), 'varie ': ('vary', 'Cookie'), 'сервер': ('сервер', 'nginx'), 'x-served-by': ('x-served-by', 'cache-iad2132-IAD' ), 'x-cache-hits': ('x-cache-hits', '1'), 'date': ('date', 'Wed, 02 Jul 2014 14:13:37 GMT'), 'x -frame-options': ('x-frame-options', 'SAMEORIGIN'), 'content-type': ('content-type', 'text/html; charset=utf-8'), 'age': ("возраст", "1483")}

В зависимости от того, что именно вы хотите от заголовков, вы можете специально получить к ним доступ после этого, но это даст вам всю информацию, содержащуюся в заголовках, хотя и в немного другом формате.

Если вы предпочитаете другой формат, вы также можете преобразовать заголовки в словарь:

import requests, json
r = requests.get("https://www.python.org/")
print json.dumps(dict(r.headers))

{"content-length": "45682", "через": "1.1 лак", "x-cache": "HIT", "accept-ranges": "bytes", "strict-transport-security": "max -age=63072000; includeSubDomains", "vary": "Cookie", "server": "nginx", "x-served-by": "cache-at50-ATL", "x-cache-hits": "5 ", "date": "Среда, 02 июля 2014 г., 14:08:15 по Гринвичу", "x-frame-options": "SAMEORIGIN", "content-type": "text/html; charset=utf-8", "возраст": "951"}

person Slater Victoroff    schedule 02.07.2014
comment
Большое спасибо @Slater Tyranus. Ваш второй метод, это именно то, что я искал. Только один вопрос из любопытства. Читая вывод вашего первого метода, я вижу, что ключи и значения находятся внутри ' '. Почему json.dumps делает это в этом случае? Должен ли допустимый формат JSON иметь значения внутри? - person The One Electronic; 02.07.2014

Если вас интересует только заголовок, сделайте запрос head. преобразовать CaseInsensitiveDict в объект dict, а затем преобразовать его в json.

import requests
import json
r = requests.head('https://www.python.org/')
rh = dict(r.headers)
json.dumps(rh)
person salmanwahed    schedule 02.07.2014

import requests
import json

r = requests.get('https://www.python.org/')
rh = r.headers

print json.dumps( dict(rh) ) # use dict()

результат:

{"content-length": "45682", "через": "1.1 лак", "x-cache": "HIT", "accept-ranges": "bytes", "strict-transport-security": "max -age=63072000; includeSubDomains", "vary": "Cookie", "server": "nginx", "x-served-by": "cache-fra1224-FRA", "x-cache-hits": "5 ", "date": "Среда, 02 июля 2014 г., 14:08:04 по Гринвичу", "x-frame-options": "SAMEORIGIN", "content-type": "text/html; charset=utf-8", "возраст": "3329"}

person furas    schedule 02.07.2014
comment
Спасибо за вашу помощь @furas - person The One Electronic; 02.07.2014

Я знаю, что это старый вопрос, но я наткнулся на него, пытаясь собрать быстрый и грязный получатель URL-адресов в стиле Python curl. Я продолжал получать сообщение об ошибке:

TypeError: Object of type 'CaseInsensitiveDict' is not JSON serializable

Приведенные выше решения хороши, если нужно немедленно вывести строку JSON, но в моем случае мне нужно было вернуть словарь заголовков python, и я хотел нормализовать капитализацию, чтобы сделать все ключи строчными.

Мое решение состояло в том, чтобы использовать понимание dict:

import requests

response = requests.head('https://www.python.org/')

my_dict = {
   'body': response.text,
   'http_status_code': response.status_code,
   'headers': {k.lower(): v for (k, v) in response.headers.items()}
}
person Everett    schedule 29.10.2019