用Python获取头部并转换为JSON(requests - urllib2 - json)

11 投票
4 回答
27949 浏览
提问于 2025-04-18 11:52

我想从一个网站获取头部信息,然后把它编码成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 个回答

0

我知道这个问题已经很老了,但我在尝试快速写一个类似于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()}
}
1
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"}

10

如果你只关心网页的头部信息,可以使用一个叫做 head 的请求。然后把 CaseInsensitiveDict 转换成一个普通的 dict 对象,再把它转成 json 格式。

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

有很多种方法可以把头部信息编码成 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"}

撰写回答