Python 从 HTTP 响应中提取 JSON

标签 python regex json http http-headers

假设我有以下 HTTP 请求:

GET /4 HTTP/1.1
Host: graph.facebook.com

服务器返回如下响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Cache-Control: private, no-cache, no-store, must-revalidate
Content-Type: text/javascript; charset=UTF-8
ETag: "539feb8aee5c3d20a2ebacd02db380b27243b255"
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Pragma: no-cache
X-FB-Rev: 1070755
X-FB-Debug: pC4b0ONpdhLwBn6jcabovcZf44bkfKSEguNsVKuSI1I=
Date: Wed, 08 Jan 2014 01:22:36 GMT
Connection: keep-alive
Content-Length: 172

{"id":"4","name":"Mark Zuckerberg","first_name":"Mark","last_name":"Zuckerberg","link":"http:\/\/www.facebook.com\/zuck","username":"zuck","gender":"male","locale":"en_US"}

由于 Content-Lengh header 取决于内容的长度,我不能简单地按 Content-Length: 172 字符串拆分。如何分别提取 JSON 和 header ?它们对我的计划都很重要。 我正在使用此代码来获取响应:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("graph.facebook.com", 80))
s.send("GET /"+str(id)+"/picture HTTP/1.1\r\nHost: graph.facebook.com\r\n\r\n")
data = s.recv(1024)
s.close()
json_string = (somehow extract this)
userdata = json.loads(json_string)

最佳答案

执行此操作的简单方法是使用 HTTP 库。例如:

import json
import urllib2

r = urllib2.urlopen("http://graph.facebook.com/{}/picture".format(id))
json_string = r.read()
userdata = json.loads(json_string)

如果你真的想自己解析它,HTTP protocol保证标题和正文由一个空行分隔,并且这将是响应中任何地方的第一个空行,所以这并不难:

data = s.recv(1024)
header, _, json_string = data.partition('\r\n\r\n')
userdata = json.loads(json_string)

这有一些明显的缺点——正如所写的那样,如果响应超过 1K,或者如果内核没有在单个 recv 中给你完整的响应,你的代码将无法工作。 (它永远不会保证这样做),或者如果服务器重定向你或在真正的响应之前给你一个 100 CONTINUE,或者如果服务器决定发回分块或 MIME-multipart 或其他响应而不是扁平体,或者……

关于Python 从 HTTP 响应中提取 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20985499/

相关文章:

python - 是否有必要传达(或预期)Python Socket TCP Buff 大小

python - 将 pandas 列中的字典转换为数据框

python - 正则表达式优化 - C enum typedef

Python 使用正则表达式重命名文件

regex - 提取除第一个单词之外的所有单词的第一个字符

ios - Swift 4 从JSON中获取相关数据

javascript - 过滤 JSON 以仅包含所需的值

python - 将 mmap 与 popen 一起使用

php - 如果列包含 Laravel 中的 JSON 编码数据,我如何在数据库中搜索值

python - Cherrypy + Autobahn websocket 在同一端口上