首页 > 解决方案 > Python 3,cgi.parse_header

问题描述

我正在尝试使用 python 从各种网站自动下载文件。我正在使用 python 3.8 和 LinuxMint。我使用的代码在大多数情况下都运行良好,但在某些情况下我会收到错误消息。如果我手动访问该网站,我可以毫无问题地下载并保存相关文件。在手动下载文件时,我注意到一个网站在文件名中使用了连字符(driv_full-holdings_20210830.csv),而另一个网站在文件名的末尾放置了一个空格,就在点+扩展名之前(SMOG_asof_20210830. xlsx)。我的预感是文件名中的连字符和空格是导致错误的原因。如何自动下载这些文件?这是我正在使用的代码和生成的错误:

from urllib.request import urlopen
from urllib.request import urlretrieve
import cgi

url = "https://www.vaneck.com/etf/equity/smog/holdings/download/xlsx/"

path = ('/home/edmint/2results/holdingPen/')

remotefile = urlopen(url)
blah = remotefile.info()['Content-Disposition']
value, params = cgi.parse_header(blah)
filename = params["filename"]
urlretrieve(url, (path + filename))


TypeError                                 Traceback (most recent call last)
<ipython-input-12-da0bd24b8e15> in <module>
      1 remotefile = urlopen(url)
      2 blah = remotefile.info()['Content-Disposition']
----> 3 value, params = cgi.parse_header(blah)
      4 filename = params["filename"]
      5 urlretrieve(url, (path + filename))

~/anaconda3/lib/python3.8/cgi.py in parse_header(line)
    231 
    232     """
--> 233     parts = _parseparam(';' + line)
    234     key = parts.__next__()
    235     pdict = {}

TypeError: can only concatenate str (not "NoneType") to str

我正在尝试的另一个网址是

https://www.globalxetfs.com/funds/driv/?download_full_holdings=true

并且产生的错误消息是相同的。

TIA

标签: python-3.x

解决方案


您的问题是remotefile.info()['Content-Disposition']None然后在尝试解析标头时尝试将输入连接到字符串时会导致上述错误。您可能应该检查是否提供了标题:对可用标题显示的快速检查Content-Disposition不存在,您可以使用print(dict(remotefile.info()).

None如果我们传递给 ,我们会得到同样的错误parse_header

In [46]: cgi.parse_header(None)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-46-0f5409738ee2> in <module>
----> 1 cgi.parse_header(None)

~\AppData\Local\Programs\Python\Python39\lib\cgi.py in parse_header(line)
    227
    228     """
--> 229     parts = _parseparam(';' + line)
    230     key = parts.__next__()
    231     pdict = {}

打印 headers 的内容,我们可以看到 header 没有提供:

>>> print(dict(remotefile.info()))
{'x-amz-id-2': 'w22MoEI/cjaJLgujA8A7eG8n9B5RCinHeVUMJGnk88mxrO/qW/TTuL68Ow0iRQTinytsRE1Mi7w=',
 'x-amz-request-id': 'WSR5HXX9FBGTNBHZ',
 'Date': 'Mon, 06 Sep 2021 02:31:20 GMT',
 'Last-Modified': 'Fri, 03 Sep 2021 10:03:12 GMT',
 'ETag': '"2b7d2ef6276c171712a7e5899a734f30"',
 'Accept-Ranges': 'bytes',
 'Content-Type': 'binary/octet-stream',
 'Server': 'AmazonS3',
 'Content-Length': '5740',
 'Connection': 'close'}

在将标头传递给parse_header. https://www.globalxetfs.com/funds/driv/?download_full_holdings=true上面的代码在您在示例中提供的 URL 上运行。


推荐阅读