我的应用程序发出大量 HTTP 请求。在不编写正则表达式的情况下,如何解析
Content-Type
标头值?例如:
text/html; charset=UTF-8
对于上下文,这是我在互联网上获取东西的代码:
from requests import head
foo = head("http://www.example.com")
我期待的输出类似于 mimetools 中的方法。例如:
x = magic("text/html; charset=UTF-8")
会输出:
x.getparam('charset') # UTF-8
x.getmaintype() # text
x.getsubtype() # HTML
requests
没有给你一个接口来解析内容类型,不幸的是,关于这个东西的标准库有点乱。所以我看到两个选择:
选项 1:去使用 python-mimeparse 第三方库。
Option 2:要将 mime 类型与
charset
之类的选项分开,您可以使用与 requests
用于在内部解析类型/编码的相同技术:使用 cgi.parse_header
.
response = requests.head('http://example.com')
mimetype, options = cgi.parse_header(response.headers['Content-Type'])
其余的应该足够简单,可以用
split
处理:
maintype, subtype = mimetype.split('/')
更新: 截至 2023 年 3 月,由于
cgi
已弃用,目前官方的做法是使用 email.message.Message
。请参阅 Philip Couling 的回答。我同意菲利普的观点,这有点恶心。
你的问题有点不清楚。我假设您正在使用某种 Web 应用程序框架,例如 Django 或 Flask?
这里是如何使用 Flask 读取 Content-Type 的例子:
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def test():
request.headers.get('Content-Type')
if __name__ == "__main__":
app.run()
自请求 2.19.0 以来,有一个
requests.utils._parse_content_type_header
函数将 Content-Type
标头拆分为无参数内容类型和参数字典。此功能不会将内容类型拆分为主要类型和子类型。
>>> requests.utils._parse_content_type_header("text/html; charset=UTF-8")
('text/html', {'charset': 'UTF-8'})
注意这个函数的名字以下划线开头:它应该是一个私有函数,所以我猜它可能会在未来的版本中被删除。作为记录,将其设为公共接口的请求被拒绝了:https://github.com/psf/requests/issues/6362
Python 有这个内置函数。 它在
email
模块中。
为此使用
email
模块似乎很疯狂,但请注意 MIME 类型是电子邮件规范的一部分(请参阅 RFC 2045)。首字母缩略词“MIME”代表“多用途互联网邮件扩展”
使用可能得到良好支持的代码可靠地执行此操作的最简单方法是使用电子邮件解析器:
from email.message import Message
_CONTENT_TYPE = "content-type"
def parse_content_type(content_type: str) -> tuple[str, dict[str,str]]:
email = Message()
email[_CONTENT_TYPE] = content_type
params = email.get_params()
# The first param is the mime-type the later ones are the attributes like "charset"
return params[0][0], dict(params[1:])
您的回复 (
foo
) 将包含带有标题的字典。尝试类似的东西:
foo.headers.get('content-type')
或打印
foo.headers
以查看所有标题。