4

Python 3.3 を使用して、.zip ファイルのダウンロードと解凍のスクリプトを作成しました。.zip の名前が変更されていない場合、これは問題なく機能します。ダウンロード時に .zip の名前を変更しようとするとzipfile.is_zipfile()、ファイルが .zip ファイルとして認識されません [ただし、WinRAR では解凍されます]。

shutil.copyfileobj()別の fdst 名 (パス全体ではない)を渡して名前を変更します。

使用するダウンロード コードは次のとおりです。

import urllib.request
import shutil
import os, os.path



def mjd_downloader(url, destdir, destfilename=None):

    req = urllib.request.Request(url)
    response = urllib.request.urlopen(req)

    #if no filename passed by destfilename, retrieve filename from ulr
    if destfilename is None:
        #need to isolate the file name from the url & download to it
        filename = os.path.split(url)[1]

    else:
        #use given filename
        filename = destfilename


    #'Download': write the content of the downloaded file to the new file

    shutil.copyfileobj(response, open(os.path.join(destdir,filename), 'wb')) 

使用される解凍コードは次のとおりです。

import zipfile
from zipfile import ZipFile
import os, os.path
import shutil

def mjd_unzipper(zippathname, outfilebasename=None):
    #outfilebasename is a name passed to the function if a new name for 
    #the content is requried   
    if zipfile.is_zipfile(zippathname) is True:
        zfileinst = ZipFile(zippathname, 'r')
        zfilepath = os.path.split(zippathname)[0]
        zlen = len(zfileinst.namelist())
        print("File path: ", zfilepath)

        if outfilebasename is not None:
            for filename in zfileinst.namelist():
                memtype = os.path.splitext(filename)[1]
                outfilename = os.path.join(outfilebasename + memtype)
                print("Extracting: ", filename, " - to: ", outfilename)
                #curzfile = zfileinst.read(filename)
                curzfile = zfileinst.open(filename)
                shutil.copyfileobj(curzfile, open(
                    os.path.join(zfilepath, outfilename), 'wb'))
        else:
            for i in range(zlen):
                extractfile = zfileinst.namelist()[i]
                memtype = os.path.splitext(extractfile)[1]
                zfileinst.extract(extractfile, path = zfilepath)

        zipfile.ZipFile.close(zfileinst)
    else:
        print("Is not a zipfile")
        pass 

どんな考えでも大歓迎です。

4

1 に答える 1

0

ダウンロード スクリプトの 24 行目で、バイナリ データを書き込むために宛先ファイルを開きました。データがメモリからファイルにプッシュされるのは、同じファイルを呼び出したときだけclose()です(ファイルを閉じずに呼び出す方法もありますが、今は思い出せません)。

with一般に、次のステートメントでファイル オブジェクトを開くのが最善です。

with open(os.path.join(destdir,filename), 'wb') as f:
    shutil.copyfileobj(response, f)

ステートメントがファイルオブジェクトで使用されると、ブロックの外に出た場合、またはブロックが他の理由で残った場合 (おそらく、インタープリターを終了させる未処理の例外) with、ブロックの最後でそれらを自動的に閉じます。break.

ステートメントを使用できない場合with(一部の古い Python バージョンではファイル オブジェクトでの使用がサポートされていないと思います)、終了後にオブジェクトに対して close() を呼び出すことができます。

f = open(os.path.join(destdir,filename), 'wb')
shutil.copyfileobj(response, f)
f.close()

これが理由であることを願っています。なぜなら、それは簡単な修正になるからです!

于 2013-01-27T21:47:23.250 に答える