Python:用于下载有效.zip文件的跨平台代码

Python:用于下载有效.zip文件的跨平台代码,python,windows,download,zip,Python,Windows,Download,Zip,我需要从网站下载并解压缩文件。以下是我正在使用的代码: #!/usr/bin/python #geoipFolder = r'/my/folder/path/ ' #Mac/Linux folder path geoipFolder = r'D:\my\folder\path\ ' #Windows folder path geoipFolder = geoipFolder[:-1] #workaround for Windows

我需要从网站下载并解压缩文件。以下是我正在使用的代码:

    #!/usr/bin/python

    #geoipFolder = r'/my/folder/path/ '     #Mac/Linux folder path
    geoipFolder = r'D:\my\folder\path\ '    #Windows folder path
    geoipFolder = geoipFolder[:-1]          #workaround for Windows escaping trailing quote
    geoipName   = 'GeoIPCountryWhois'
    geoipURL    = 'http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip'

    import urllib2
    response = urllib2.urlopen(geoipURL)

    f = open('%s.zip' % (geoipFolder+geoipName),"w")
    f.write(repr(response.read()))
    f.close()

    import zipfile  
    zip = zipfile.ZipFile(r'%s.zip' % (geoipFolder+geoipName))
    zip.extractall(r'%s' % geoipFolder)
此代码适用于Mac和Linux设备,但不适用于Windows。此时,将写入.zip文件,但脚本会引发以下错误:

    zipfile.BadZipfile: File is not a zip file
我也无法使用Windows资源管理器解压缩该文件。它说:

    The compressed (zipped) folder is empty.
但是,磁盘上的文件是6MB大的

关于我在Windows上做错了什么的想法


谢谢

您的zipfile在windows上已损坏,因为您正在以写/文本模式打开文件(行终止符转换会破坏二进制数据):

您必须以写/二进制模式打开,如下所示:

f = open('%s.zip' % (geoipFolder+geoipName),"wb")
(当然,在Linux上仍然有效)

总之,这是一种更具python风格的方法,使用
with
块(并删除
repr
):

编辑:无需将文件写入磁盘,您可以使用
io.BytesIO
,因为
ZipFile
对象接受文件句柄作为第一个参数

import io
import zipfile  

with open('{}{}.zip'.format(geoipFolder,geoipName),"wb") as f:
    outbuf = io.BytesIO(f.read())

zip = zipfile.ZipFile(outbuf)  # pass the fake-file handle: no disk write, no temp file
zip.extractall(r'%s' % geoipFolder)

您可能不需要处理
urlopen
。你可以简单地使用
urlretrieve(URL,路径到文件)
,你说对了两次Jean François!我需要“wb”和删除repr()以在Windows上获得有效的.zip文件。谢谢你!!检查我的编辑,您可以避免使用temp.zip文件。请接受你认为能解决问题的答案。
with open('{}{}.zip'.format(geoipFolder,geoipName),"wb") as f:
     f.write(response.read())
import io
import zipfile  

with open('{}{}.zip'.format(geoipFolder,geoipName),"wb") as f:
    outbuf = io.BytesIO(f.read())

zip = zipfile.ZipFile(outbuf)  # pass the fake-file handle: no disk write, no temp file
zip.extractall(r'%s' % geoipFolder)