Я загружаю файл с использованием функции get
библиотеки Python requests
. Для хранения файла я хотел бы определить имя файла, который они будут использовать для веб-браузера для диалога «сохранить» или «сохранить как ...».Как определить имя файла, загруженного с помощью HTTP в Python?
Легко, правда? Я могу только get it from the Content-Disposition
заголовок HTTP, доступный на объект ответа:
import re
d = r.headers['content-disposition']
fname = re.findall("filename=(.+)", d)
Но более пристально глядя на эту тему, это не , что легко:
Согласно RFC 6266 section 4.3, и грамматика в section 4.1, это может быть некорректный токен (например, the_report.pdf
) или строка с кавычками, которая также может содержать пробелы (например, "the report.pdf"
) и escape-последовательности. Кроме того,
, когда оба «имя файла» и «имя файла *» присутствуют в одном значении поля заголовка, [мы] должны выбрать «имя файла *» и игнорировать «имя файла».
Значение filename*
, однако, является yet a bit more complicated, чем один из filename
.
Кроме того, RFC, похоже, допускает дополнительные пробелы вокруг =
.
Таким образом, для examples listed in the RFC, я бы хотел следующие результаты:
Имя файла:Content-Disposition: Attachment; filename=example.html
example.html
Имя файла:Content-Disposition: INLINE; FILENAME= "an example.html"
an example.html
Имя файла:Content-Disposition: attachment; filename*= UTF-8''%e2%82%ac%20rates
€ rates
файла:Content-Disposition: attachment; filename="EURO rates"; filename*=utf-8''%e2%82%ac%20rates
€ rates
здесь тоже (неEURO rates
какfilename*
имеет преимущество)
Теперь, я мог бы легко адаптировать регулярное выражение для учета переменных пробельного вокруг =
, но иметь его ручку все остальные варианты тоже будут довольно громоздкими. (При цитировании и побеге я даже не уверен, что RegEx может охватывать все случаи. Может быть, они могут, поскольку в нем нет привязки фигурной скобки.)
Итак, Мне нужно реализовать полномасштабный синтаксический анализатор , или я могу определить имя файла в соответствии с RFC 6266 несколькими звонками в библиотеку HTTP (возможно, requests
)? Поскольку RFC 6266 является частью стандарта HTTP, я могу себе представить, что некоторые библиотеки, специализированные по HTTP, уже охватывают это. (Итак, у меня есть also asked on Software Recommendations SE.)
Что вы подразумеваете под «нестандартными пробелами»? Пробел в местах, где стандарт не допускает пробелов? Или пробелы UNICODE, которые не являются частью 7-разрядного ASCII? –
@ das-g Не исследовали достаточно, чтобы сказать вам точно. Оказывается, у 'parse_headers' есть опция' relaxed', которая помогает с этим. Проверьте код [здесь] (https://github.com/g2p/rfc6266/blob/master/rfc6266.py#L209). – Kupiakos