2014-07-02 11 views
5

Sto cercando di ottenere l'intestazione da un sito Web, la codifica in JSON per scriverlo in un file. Ho provato due modi diversi senza successo.Ottieni un'intestazione con Python e converti in JSON (richieste - urllib2 - json)

PRIMO con urllib2 e JSON

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

in questo modo ottengo l'errore:

TypeError: is not JSON serializable

così cerco di aggirare questo problema convertendo l'oggetto in una stringa -> json_header = str (intestazione) In questo modo posso json_header = json.dumps (intestazione), ma l'uscita è strano:

"Date: Wed, 02 Jul 2014 13:33:37 GMT\r\nServer: nginx\r\nContent-Type: text/html; charset=utf-8\r\nX-Frame-Options: SAMEORIGIN\r\nContent-Length: 45682\r\nAccept-Ranges: bytes\r\nVia: 1.1 varnish\r\nAge: 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"

secondo con richieste

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

{'content-length': '45682', 'via': '1.1 varnish', 'x-cache': 'HIT', 'accept-ranges': 'bytes', 'strict-transport-security': 'max-age=63072000; includeSubDomains', 'vary': 'Cookie', 'server': 'nginx', 'x-served-by': 'cache-fra1226-FRA', 'x-cache-hits': '14', 'date': 'Wed, 02 Jul 2014 13:39:33 GMT', 'x-frame-options': 'SAMEORIGIN', 'content-type': 'text/html; charset=utf-8', 'age': '1619'}

In questo modo l'uscita è più JSON simile ma ancora non OK (vedere la ‘‘invece di ““e altre cose come i = e;). Evidentemente c'è qualcosa (o molto) che non sto facendo nel modo giusto. Ho provato a leggere la documentazione dei moduli ma non riesco a capire come risolvere questo problema. Grazie per il vostro aiuto.

risposta

8

Ci sono più di un paio di modi per codificare le intestazioni come JSON, ma il mio primo pensiero sarebbe quello di convertire l'attributo headers a un dizionario vero e proprio invece di accedere come 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'), 'via': ('via', '1.1 varnish'), 'x-cache': ('x-cache', 'HIT'), 'accept-ranges': ('accept-ranges', 'bytes'), 'strict-transport-security': ('strict-transport-security', 'max-age=63072000; includeSubDomains'), 'vary': ('vary', 'Cookie'), 'server': ('server', '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': ('age', '1483')}

A seconda esattamente quello che vuoi sulle intestazioni puoi specificatamente accedervi dopo questo, ma questo ti darà tutte le informazioni contenute nelle intestazioni, se in un formato leggermente diverso.

Se si preferisce un formato diverso, è anche possibile convertire le intestazioni a un dizionario:

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

{"content-length": "45682", "via": "1.1 varnish", "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": "Wed, 02 Jul 2014 14:08:15 GMT", "x-frame-options": "SAMEORIGIN", "content-type": "text/html; charset=utf-8", "age": "951"}

+0

Grazie mille @Slater Tyranus. Il tuo secondo metodo è esattamente quello che stavo cercando. Solo una domanda per curiosità. Leggendo l'output del tuo primo metodo vedo che chiavi e valori sono dentro ''. Perché json.dumps lo fa in quel caso? Se un formato JSON valido ha valori all'interno di ""? –

1
import requests 
import json 

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

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

risultato:

{"content-length": "45682", "via": "1.1 varnish", "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": "Wed, 02 Jul 2014 14:08:04 GMT", "x-frame-options": "SAMEORIGIN", "content-type": "text/html; charset=utf-8", "age": "3329"}

+0

Grazie per il vostro aiuto @furas –

6

Se siete interessati solo nel intestazione, effettuare una richiesta head. convertire CaseInsensitiveDict in un oggetto dict e convertirlo in json.

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