如果 link 不包含 .pdf,如何测试 link 目标是否为 pdf 文件

How to test if a link target is a pdf file if the link does not contain .pdf

我正在使用 selenium 抓取一堆以混合格式和样式提供的文件 - 试图同时处理 html 和 pdf,我在目标时遇到了一个问题link 的一个是 pdf 文件,但 link 本身不包含 '.pdf' e.g., and(请注意,一个自动下载,一个只显示文件 - 至少在 chrome - 所以可能还需要对两种不同类型的 pdf 目标进行测试?)

有没有办法以编程方式判断 link 的目标是否为 pdf,这比仅检查它是否以 .pdf 结尾更智能?

无论内容如何,​​我都不能只下载文件,因为我对 html 文件有不同的处理方式,我想在其中关注辅助 links 并查看是否可以找到pdfs,如果目标直接是 pdf,这将不起作用。

ETA:接受的答案非常有效 - linked 潜在的欺骗是为了在文件系统上测试,而不是为了下载,所以我认为这是无效的,当然下面的答案更适合这个情况。

Selenium(或 Chrome)检查 'Content-Type' headers 并选择要执行的操作。您还可以自己检查 URL 的 'Content-Type' 使用 requests 如下所示:

>>> r = requests.head('https://resus.org.au/?wpfb_dl=17')
>>> pprint.pprint(dict(r.headers))
{'Accept-Ranges': 'bytes',
  'Age': '8518',
  'Cache-Control': 'no-cache, must-revalidate, max-age=0',
  'Connection': 'keep-alive',
  'Content-Description': 'File Transfer',
  'Content-Disposition': 'attachment; '
  'filename="anzcor-guideline-6-compressions-apr-2021.pdf"',
    'Content-Length': '535677',
  'Content-Md5': '90AUQUZu0vFGJ7cBPvRxcg==',
  'Content-Security-Policy': 'upgrade-insecure-requests',
  'Content-Type': 'application/pdf',
  'Date': 'Wed, 19 Jan 2022 11:20:06 GMT',
  'Expires': 'Wed, 11 Jan 1984 05:00:00 GMT',
  'Last-Modified': 'Wed, 19 Jan 2022 08:58:08 GMT',
  'Pragma': 'no-cache',
  'Server': 'openresty',
  'Strict-Transport-Security': 'max-age=300, max-age=31536000; '
  'includeSubDomains',
    'Vary': 'User-Agent',
  'X-Backend': 'local',
  'X-Cache': 'cached',
  'X-Cache-Hit': 'HIT',
  'X-Cacheable': 'YES:Forced',
  'X-Content-Type-Options': 'nosniff',
  'X-Xss-Protection': '1; mode=block'}

如你所见,你的两个link的'Content-Type'都是'application/pdf':

>>> r.headers['Content-Type']
'application/pdf'

所以你可以只检查 requests.head(link).headers['Content-Type'] 的输出,然后做任何你想做的事情。


目前(2022 年 1 月 19 日),您问题中的第一个 link 将我重定向到 404 页面。第二个仍然可以访问,但是需要通过将 link 的起始部分从 http:// 更改为 https://.

来使用 HTTPS 协议

但是无论如何,如果 URL 没有将您重定向到任何其他页面,那么这个答案就不是 out-of-date。如果 URL 是,请通过检查 status_code 请求最新的 URL 如果它是 301:

>>> r = requests.head('http://resus.org.au/?wpfb_dl=17')
>>> r.status_code
301
>>> r = requests.head('https://resus.org.au/?wpfb_dl=17')
>>> r.status_code
200
>>>