0

我一直在尝试使用 python 编写代码来对该 ftp 的主目录进行分级并将其存档到本地 pc 中。我不是业余编码员,python 对我来说相当新。我现在得到的错误是。

File "C:\Users\Ali\Desktop\ftp_archiving_script.py", line 24, in <module>
ftpDownload = ftp.retrbinary('RETR', filename)

代码:

    from ftplib import FTP
import zipfile
import os
try:
    import zlib
    compression = zipfile.ZIP_DEFLATED
except:
    compression = zipfile.ZIP_STORED
modes = { zipfile.ZIP_DEFLATED: "deflated",
          zipfile.ZIP_STORED: "stored",
    }

#print "Logging in..."
with FTP('xxx.xxx.xxx') as ftp: #hostname goes here
    ftp.login('xxxx','xxxx') #user followed by pass
    #print "changing to root directory"
    ftp.mlsd('//')
    #print "Accessing files"
    filenames = []
    #print filenames
    ftp.retrlines('NLST', filenames.append)
    try:
        for filename in filenames:
            ftpDownload = ftp.retrbinary('RETR', filename)
            with ZipFile(os.path.join('C:\\','DC_archive.zip'), 'w') as myzip:
                myzip.write(ftpDownload, compress_type=compression)
                myzip.close()
    finally:
        #print "closing"
        ftp.close()
    ftp.quit()

任何人都可以在这个问题上启发我。

谢谢,

更新

try:
    for filename in filenames:
        with io.StringIO() as fObject:
            ftp.retrbinary('RETR %s' %filename, fObject.write)
            with ZipFile(os.path.join('C:\\','DC_archive.zip'), 'w') as myzip:
                myzip.write(fObject, compress_type=compression)
                myzip.close()

更新了@fals 的回溯...这也是在下面使用您的代码,而不是我在顶部的代码。

    Traceback (most recent call last):
  File "C:\Users\Ali\Desktop\ftp_archive2.py", line 20, in <module>
    ftpDownload = ftp.retrbinary('RETR ' + filename, f.write)
  File "C:\Python33\lib\ftplib.py", line 424, in retrbinary
    with self.transfercmd(cmd, rest) as conn:
  File "C:\Python33\lib\ftplib.py", line 386, in transfercmd
    return self.ntransfercmd(cmd, rest)[0]
  File "C:\Python33\lib\ftplib.py", line 352, in ntransfercmd
    resp = self.sendcmd(cmd)
  File "C:\Python33\lib\ftplib.py", line 259, in sendcmd
    return self.getresp()
  File "C:\Python33\lib\ftplib.py", line 233, in getresp
    raise error_perm(resp)
ftplib.error_perm: 550 File not found
4

2 回答 2

1

来自ftplib.retrbinary的 Python 文档:

FTP.retrbinary(命令,回调[,maxblocksize [,休息]])

以二进制传输模式检索文件。命令应该是适当的 RETR 命令:“RETR 文件名”。为接收到的每个数据块调用回调函数,并使用单个字符串参数给出数据块。

它没有表明它返回一个类似文件的对象或字符串。

相反,您必须创建自己的回调来写入文件对象。

with open('my-downloaded-file', 'wb') as f:
    ftp.retrbinary('RETR %s' % filename, f.write)

这里f.write是回调,它将在数据从套接字到达时接收数据。如果不想使用 将文件保存到磁盘open,可以使用StringIO模块模拟内存中的文件。

于 2013-07-05T04:01:44.687 回答
0

试试下面的代码:

import ftplib
from io import BytesIO
import os
import zipfile

REMOTE_HOST = 'xxx.xxx.xxx'
REMOTE_USER = '...'
REMOTE_PASS = '...'
REMOTE_DIR_PATH = '//'
LOCAL_ZIP_PATH = os.path.join(os.path.expanduser('~'), 'Desktop', 'DC_archive.zip')

ftp = ftplib.FTP(REMOTE_HOST)
try:
    ftp.login(REMOTE_USER, REMOTE_PASS)
    ftp.cwd(REMOTE_DIR_PATH)
    filenames = ftp.nlst()
    with zipfile.ZipFile(LOCAL_ZIP_PATH, 'w') as zf:
        for filename in filenames:
            with BytesIO() as f:
                try:
                    ftpDownload = ftp.retrbinary('RETR ' + filename, f.write)
                    zf.writestr(filename, f.getvalue())
                except ftplib.Error as e:
                    print('Skip {}: {}'.format(filename, e))
finally:
    ftp.quit()
于 2013-07-05T04:18:23.410 回答