在 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 在这里使用并支持urllibmsg 是作为 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”。

【讨论】:

小心,不要覆盖python dict【参考方案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 响应的主要内容,如果未能解决你的问题,请参考以下文章

解析来自 TCP 流的 HTTP 响应

python爬虫---从零开始Urllib库

在 python 中解析 IMAP 响应

Python urllib的urlretrieve()函数解析 (显示下载进度)

如何格式化 XML 响应 - Python

爬虫学习推荐目录