用Python获取头部并转换为JSON(requests - 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
这样做的时候我遇到了一个错误:
类型错误:不是JSON可序列化的
所以我试着绕过这个问题,把对象转换成字符串 -> json_header = str(header) 这样我可以用json_header = json.dumps(header),但输出的结果很奇怪:
"日期:2014年7月2日 星期三 13:33:37 GMT\r\n服务器:nginx\r\n内容类型: text/html; 字符集=utf-8\r\nX-Frame-Options: SAMEORIGIN\r\n内容长度:45682\r\n接受范围:字节\r\n通过: 1.1 varnish\r\n年龄:1263\r\nX-Served-By:cache-fra1220-FRA\r\nX-Cache:命中\r\nX-Cache-Hits:2\r\n变化:Cookie\r\n严格传输安全: 最大年龄=63072000; 包含子域名\r\n连接:关闭\r\n"
第二种方法是用requests
import requests
r = requests.get(“https://www.python.org/”)
rh = r.headers
print rh
{'内容长度': '45682', '通过': '1.1 varnish', 'X-Cache': '命中', '接受范围': '字节', '严格传输安全': '最大年龄=63072000; 包含子域名', '变化': 'Cookie', '服务器': 'nginx', 'X-Served-By': 'cache-fra1226-FRA', 'X-Cache-Hits': '14', '日期': '2014年7月2日 星期三 13:39:33 GMT', 'X-Frame-Options': 'SAMEORIGIN', '内容类型': 'text/html; 字符集=utf-8', '年龄': '1619'}
这样输出的结果更像JSON格式,但还是不太对(比如用‘ ’代替了“ ”,还有其他像=和;的东西)。显然我有很多地方做得不对。我试着阅读模块的文档,但我还是不明白该怎么解决这个问题。谢谢你的帮助。
4 个回答
我知道这个问题已经很老了,但我在尝试快速写一个类似于Python的 curl
的网址获取工具时碰到了这个问题。我一直收到一个错误:
TypeError: Object of type 'CaseInsensitiveDict' is not JSON serializable
上面的解决方案在需要立即输出一个JSON字符串时很好用,但在我的情况下,我需要返回一个包含头信息的Python字典,并且我想把所有的键都变成小写字母。
我的解决办法是使用一种叫做 字典推导式 的方法:
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()}
}
import requests
import json
r = requests.get('https://www.python.org/')
rh = r.headers
print json.dumps( dict(rh) ) # use dict()
结果:
{"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": "2014年7月2日 14:08:04 GMT", "x-frame-options": "SAMEORIGIN", "content-type": "text/html; charset=utf-8", "age": "3329"}
如果你只关心网页的头部信息,可以使用一个叫做 head
的请求。然后把 CaseInsensitiveDict
转换成一个普通的 dict
对象,再把它转成 json
格式。
import requests
import json
r = requests.head('https://www.python.org/')
rh = dict(r.headers)
json.dumps(rh)
有很多种方法可以把头部信息编码成 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'), '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')}
根据你想要的头部信息,你可以在这之后具体访问它们,不过这样做会让你得到所有头部信息,只是格式稍微不同而已。
如果你更喜欢其他格式,也可以把头部信息转换成字典:
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"}