在 Python 中解析 HTTP 响应
Posted
技术标签:
【中文标题】在 Python 中解析 HTTP 响应【英文标题】:Parsing HTTP Response in Python 【发布时间】:2014-05-27 19:17:00 【问题描述】:我想处理THIS url 处的信息。我可以成功打开它并阅读它的内容。但我真正想做的是把我不想要的东西都扔掉,把我想保留的东西操纵起来。
有没有办法将字符串转换为 dict 以便我可以对其进行迭代?还是我只需要按原样解析它(str 类型)?
from urllib.request import urlopen
url = 'http://www.quandl.com/api/v1/datasets/FRED/GDP.json'
response = urlopen(url)
print(response.read()) # returns string with info
【问题讨论】:
网址可能会损坏,最好在您的问题中包含有代表性的示例。 【参考方案1】:当我打印response.read()
时,我注意到b
被预先添加到字符串中(例如b'"a":1,..
)。 “b”代表字节,用作您正在处理的对象类型的声明。因为,我知道可以使用json.loads('string')
将字符串转换为字典,所以我只需要将字节类型转换为字符串类型。我通过解码对 utf-8 decode('utf-8')
的响应来做到这一点。一旦它是字符串类型,我的问题就解决了,我可以轻松地遍历dict
。
我不知道这是否是最快或最“pythonic”的编写方式,但它确实有效,而且总是有时间进行优化和改进!我的解决方案的完整代码:
from urllib.request import urlopen
import json
# Get the dataset
url = 'http://www.quandl.com/api/v1/datasets/FRED/GDP.json'
response = urlopen(url)
# Convert bytes to string type and string type to dict
string = response.read().decode('utf-8')
json_obj = json.loads(string)
print(json_obj['source_name']) # prints the string with 'source_name' key
【讨论】:
【参考方案2】:我猜在 python 3.4 中事情已经发生了变化。这对我有用:
print("resp:" + json.dumps(resp.json()))
【讨论】:
没有json
属性。不要混淆requests
库和urllib.request
。【参考方案3】:
json
在 Python 3 中使用 Unicode 文本(JSON 格式本身仅根据 Unicode 文本定义),因此您需要对 HTTP 响应中接收到的字节进行解码。 r.headers.get_content_charset('utf-8')
获取你的字符编码:
#!/usr/bin/env python3
import io
import json
from urllib.request import urlopen
with urlopen('https://httpbin.org/get') as r, \
io.TextIOWrapper(r, encoding=r.headers.get_content_charset('utf-8')) as file:
result = json.load(file)
print(result['headers']['User-Agent'])
这里不用io.TextIOWrapper
:
#!/usr/bin/env python3
import json
from urllib.request import urlopen
with urlopen('https://httpbin.org/get') as r:
result = json.loads(r.read().decode(r.headers.get_content_charset('utf-8')))
print(result['headers']['User-Agent'])
【讨论】:
在 Python 3 中,使用r.msg.get_content_charset
。 docs.python.org/3/library/…
@PeppeL-G: 来自HTTPResponse
来源:"headers
在这里使用并支持urllib
。msg
是作为 http 客户端的向后兼容层提供的。 "
哦,对不起,我没有太多的 Python 经验,但你可能是对的。我正在使用来自http.client
模块的HTTPResponse
类,现在我看到存在一些差异(这个类包含msg
字段和headers
字段(相同的值),但我只找到了文档对于msg
字段,所以我认为headers
是为了向后兼容而保留的。我的错误。
@PeppeL-G 这可能是文档中的一个错误,因为headers
是一个比msg
更好的存储HTTP 标头的属性名称。如果您认为其他人可能有同样的问题;你可以submit a simple documentation patch,提到可以使用headers
并且msg
存在是为了向后兼容。【参考方案4】:
您也可以使用 python 的 requests 库。
import requests
url = 'http://www.quandl.com/api/v1/datasets/FRED/GDP.json'
response = requests.get(url)
dict = response.json()
现在您可以像操作 python 字典一样操作“dict”。
【讨论】:
小心,不要覆盖pythondict
【参考方案5】:
TL&DR:当您通常从服务器获取数据时,它以字节为单位发送。理由是这些字节需要由接收者“解码”,接收者应该知道如何使用数据。您应该在到达时解码二进制文件,而不是得到“b”(字节),而是一个字符串。
用例:
import requests
def get_data_from_url(url):
response = requests.get(url_to_visit)
response_data_split_by_line = response.content.decode('utf-8').splitlines()
return response_data_split_by_line
在此示例中,我将收到的内容解码为 UTF-8。出于我的目的,我将它逐行拆分,这样我就可以使用 for 循环遍历每一行。
【讨论】:
以上是关于在 Python 中解析 HTTP 响应的主要内容,如果未能解决你的问题,请参考以下文章