das*_*s-g 14 python content-disposition http-headers python-requests
我使用getPython requests库的功能下载文件.为了存储文件,我想确定Web浏览器用于"保存"或"另存为..."对话框的文件名.
容易,对吗?我可以从Content-Disposition HTTP头中获取它,可以在响应对象上访问:
import re
d = r.headers['content-disposition']
fname = re.findall("filename=(.+)", d)
Run Code Online (Sandbox Code Playgroud)
但在这个话题更加密切关注,不在于简单:
根据RFC 6266第4.3节和4.1节中的语法,值可以是不带引号的标记(例如the_report.pdf)或带引号的字符串,它也可以包含空格(例如"the report.pdf")和转义序列.进一步,
当"filename"和"filename*"都出现在单个标题字段值中时,[我们]应该选择"filename*"并忽略"filename".
filename*但是,它的价值比那个更复杂filename.
此外,RFC似乎允许额外的空白围绕=.
Content-Disposition: Attachment; filename=example.html
Run Code Online (Sandbox Code Playgroud)
文件名: example.htmlContent-Disposition: INLINE; FILENAME= "an example.html"
Run Code Online (Sandbox Code Playgroud)
文件名: an example.htmlContent-Disposition: attachment;
filename*= UTF-8''%e2%82%ac%20rates
Run Code Online (Sandbox Code Playgroud)
文件名: € ratesContent-Disposition: attachment;
filename="EURO rates";
filename*=utf-8''%e2%82%ac%20rates
Run Code Online (Sandbox Code Playgroud)
文件名:€ rates这里也是(不是EURO rates,filename*优先)现在,我可以很容易地调整正则表达式来解释周围的变量空格=,但是让它处理所有其他变量也会变得相当笨拙.(通过引用和转义,我甚至不确定RegEx是否可以涵盖所有情况.也许它们可以,因为没有涉及支撑嵌套.)
那么我是否必须实现一个完整的解析器,或者我可以根据RFC 6266通过对HTTP库(可能requests本身)的一些调用来确定文件名?由于RFC 6266是HTTP标准的一部分,我可以想象一些专门用于HTTP的库已经涵盖了这一点.(所以我也问过软件建议SE.)
Aly*_*sen 10
该rfc6266库似乎完全符合您的需求.它可以解析原始标头,requests响应和urllib2响应.它在PyPI上.
一些例子:
>>> import rfc6266, requests
>>> rfc6266.parse_headers('''Attachment; filename=example.html''').filename_unsafe
'example.html'
>>> rfc6266.parse_headers('''INLINE; FILENAME= "an example.html"''').filename_unsafe
'an example.html'
>>> rfc6266.parse_headers(
'''attachment; '''
'''filename*= UTF-8''%e2%82%ac%20rates''').filename_unsafe
'€ rates'
>>> rfc6266.parse_headers(
'''attachment; '''
'''filename="EURO rates"; '''
'''filename*=utf-8''%e2%82%ac%20rates''').filename_unsafe
'€ rates'
>>> r = requests.get('http://example.com/€ rates')
>>> rfc6266.parse_requests_response(r).filename_unsafe
'€ rates'
Run Code Online (Sandbox Code Playgroud)
作为一个说明,虽然:这个库并没有像在头非标准空白.
到 2022 年,原始答案中推荐的Python 模块rfc6266似乎已被放弃,并且无法真正与较新版本的 Python 一起使用。
好消息是有一个名为Pyrfc6266的替换模块(其中之一,但这个确实有效!)
它可以通过以下方式安装:
pip install pyrfc6266
Run Code Online (Sandbox Code Playgroud)
并使用相同的方式:
import pyrfc6266
pyrfc6266.parse_filename('attachment; filename="foo.html"')
Run Code Online (Sandbox Code Playgroud)
或者
import requests
import pyrfc6266
response = requests.get('http://httpbin.org/response-headers?Content-Disposition=attachment;%20filename%3d%22foo.html%22')
pyrfc6266.requests_response_to_filename(response)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4404 次 |
| 最近记录: |