如何使用Python请求获取pdf文件名?

kra*_*r65 25 python pdf filenames python-requests

我正在使用Python 请求lib从Web获取PDF文件.这工作正常,但我现在也想要原始文件名.如果我在Firefox中转到PDF文件并单击download它已经定义了一个文件名以保存pdf.我如何获得此文件名?

例如:

import requests
r = requests.get('http://www.researchgate.net/profile/M_Gotic/publication/260197848_Mater_Sci_Eng_B47_%281997%29_33/links/0c9605301e48beda0f000000.pdf')
print r.headers['content-type']  # prints 'application/pdf'
Run Code Online (Sandbox Code Playgroud)

我查了一下r.headers有趣的东西,但那里没有文件名.我实际上希望有类似的东西r.filename......

有谁知道如何获取带有请求库的下载PDF文件的文件名?

小智 50

它在http标头中指定content-disposition.所以要提取你要做的名字:

import re
d = r.headers['content-disposition']
fname = re.findall("filename=(.+)", d)[0]
Run Code Online (Sandbox Code Playgroud)

通过正则表达式(re模块)从字符串中提取的名称.

  • findall返回匹配列表.你需要一个像这样的索引`fname = re.findall("filename =(.+)",d)[0]`. (5认同)
  • @Michael-O 尝试使用 `"filename=\"(.+)\""` 删除引号 (5认同)

Nil*_*lpo 13

基于其他一些答案,这就是我的做法。如果没有Content-Disposition标题,我从下载 URL 解析它:

import re
import requests
from requests.exceptions import RequestException


url = 'http://www.example.com/downloads/sample.pdf'

try:
    with requests.get(url) as r:

        fname = ''
        if "Content-Disposition" in r.headers.keys():
            fname = re.findall("filename=(.+)", r.headers["Content-Disposition"])[0]
        else:
            fname = url.split("/")[-1]

        print(fname)
except RequestException as e:
    print(e)
Run Code Online (Sandbox Code Playgroud)

可以说有更好的方法来解析 URL 字符串,但为了简单起见,我不想涉及更多的库。

  • 我建议在 else 子句中调用 `urllib.parse.unquote`,这样文件名中就不会出现 `%20`。 (2认同)

Mak*_*jov 7

显然,对于这个特定的资源,它在:

r.headers['content-disposition']
Run Code Online (Sandbox Code Playgroud)

但不知道是否总是这样.


myi*_*rim 5

您可以用于werkzeug选项标头https://werkzeug.palletsprojects.com/en/0.15.x/http/#werkzeug.http.parse_options_header

>>> import werkzeug


>>> werkzeug.http.parse_options_header('text/html; charset=utf8')
('text/html', {'charset': 'utf8'})
Run Code Online (Sandbox Code Playgroud)


小智 5

从内容处理中获取文件名的简单 python3 实现:

import requests
response = requests.get(<your-url>)
print(response.headers.get("Content-Disposition").split("filename=")[1])
Run Code Online (Sandbox Code Playgroud)