使用 Python 获取标头并转换为 JSON(请求 - urllib2 - json)

Posted

技术标签:

【中文标题】使用 Python 获取标头并转换为 JSON(请求 - urllib2 - json)【英文标题】:Get a header with Python and convert in JSON (requests - urllib2 - json) 【发布时间】:2014-08-23 08:33:20 【问题描述】:

我正在尝试从网站获取标题,将其编码为 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\r\n服务器:nginx\r\n内容类型: 文本/html; charset=utf-8\r\nX-Frame-选项: SAMEORIGIN\r\nContent-Length: 45682\r\nAccept-Ranges: bytes\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 -运输安全: 最大年龄=63072000; includeSubDomains\r\n连接:关闭\r\n"

第二个请求

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

'content-length': '45682', 'via': '1.1 varnish', 'x-cache': 'HIT', “接受范围”:“字节”,“严格传输安全”: '最大年龄=63072000; includeSubDomains', 'vary': 'Cookie', 'server': 'nginx','x-served-by':'cache-fra1226-FRA','x-cache-hits':'14', “日期”:“格林威治标准时间 2014 年 7 月 2 日星期三 13:39:33”,“x-frame-options”: 'SAMEORIGIN', '内容类型': 'text/html;字符集=utf-8','年龄': '1619'

通过这种方式,输出更像 JSON,但仍然不正常(请参阅“”而不是“”和其他东西,如 = 和 ;)。 显然有些事情(或很多)我做得不对。 我试图阅读模块的文档,但我不明白如何解决这个问题。 感谢您的帮助。

【问题讨论】:

【参考方案1】:

将标头编码为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 清漆'),'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'), “内容类型”:(“内容类型”,“文本/html;字符集=utf-8”),“年龄”: ('年龄', '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”, “接受范围”:“字节”,“严格传输安全”: "max-age=63072000; includeSubDomains", "vary": "Cookie", "server": “nginx”、“x-served-by”:“cache-at50-ATL”、“x-cache-hits”:“5”、“日期”: “格林威治标准时间 2014 年 7 月 2 日星期三 14:08:15”,“x-frame-options”:“SAMEORIGIN”, "content-type": "text/html; charset=utf-8", "age": "951"

【讨论】:

非常感谢@Slater Tyranus。你的第二种方法正是我想要的。只是出于好奇提出一个问题。阅读您的第一个方法的输出,我看到键和值在“”内。为什么 json.dumps 在这种情况下会这样做?有效的 JSON 格式是否应该在“”中包含值?【参考方案2】:
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”,“日期”:“格林威治标准时间 2014 年 7 月 2 日星期三 14:08:04”,“x-frame-options”:“SAMEORIGIN”,“content-type”:“text/html; charset=utf- 8", "年龄": "3329"

【讨论】:

感谢您的帮助@furas【参考方案3】:

如果您只对标头感兴趣,请发出head 请求。将CaseInsensitiveDict 转换为dict 对象,然后将其转换为json

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

【讨论】:

【参考方案4】:

我知道这是一个老问题,但我在尝试组合一个快速而肮脏的 Python curl-esque URL getter 时偶然发现了它。我一直收到错误:

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

如果需要立即输出 JSON 字符串,上述解决方案很好,但在我的情况下,我需要返回标题的 python 字典,并且我想规范化大写以使所有键都小写。

我的解决方案是使用dict comprehension:

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()

【讨论】:

以上是关于使用 Python 获取标头并转换为 JSON(请求 - urllib2 - json)的主要内容,如果未能解决你的问题,请参考以下文章

使用 python 将 JSON 转换为 CSV

怎样从java后台获取json字符串并转换为json对象输出?

Python-解析电子邮件正文并截断 MIME 标头

.net 数据表转换成json

将 Python Pandas 数据框转换为 JSon 格式并通过使用 Python 添加其列名保存到 MongoDB 数据库中

如何使用 python 脚本将 JSON 数据转换为 PDF