使用Python脚本从FTP下载.pdf文件

2 投票
3 回答
2677 浏览
提问于 2025-04-16 08:53

我可以用Python里的ftplib从FTP下载文件,但我现在是死死地写了文件名(R.pdf),这样只能下载这个特定的文件(R.pdf)。请问有没有办法用Python把FTP上所有扩展名为.PDF的文件都下载到我的本地系统呢?我在Shell里只需要用*.pdf就能做到。

3 个回答

0

使用两个Python模块,分别是 globwget。你的代码片段可以像这样:

import glob
import wget

list_to_download = glob.glob(url+'*.pdf')

for file in list_to_download:
    wget.download(file)
1

我没有可以尝试的FTP服务器,不过简单看了一下文档,似乎这件事是做不到的。

不过,你可以使用dirnlst命令来获取远程服务器上的文件列表,然后再通过循环一个一个地下载这些文件。

4

把主机、用户名和密码换成你的账号信息,另外把 'public_html/soleil' 替换成你想下载的 PDF 文件所在目录的地址,下面的代码应该就可以用了。

from ftplib import *
from os import listdir
from os.path import getsize


ftp_dt = FTP(host,user,password)
ftp_pi = FTP(host,user,password)
print '\n- Ouverture de connection et logging : OK'


ftp_dt.cwd('public_html/soleil')
ftp_pi.cwd('public_html/soleil')


def func(content, li = [0], la = [], si = [0], memname = ['']):
    if name!=memname[0]:
        memname[0],li[0:1],la[:],si[0:1] = name,[0],[],[0]
    li[0] = li[0] + 1
    si[0] = si[0] + len(content)
    la.append(str(len(content)))
    if li[0]%8==0:
        print '  '.join(la) +\
              '   total: '+str(li[0])+' chunks,  '+str(si[0])+' bytes'
        la[:] = []
    f.write(content)


li_files = []
for name in ftp_dt.nlst():
    try:
        ftp_dt.size(name)
        if name not in ('.','..') and name[-4:]=='.pdf':
            li_files.append(name)
    except:
        pass


if li_files:
    for name in li_files:
        print '\n- Downloading  '+name

        with open('E:\\PDF\\DOWNS\\'+name,'wb') as f:
            ftp_pi.retrbinary('RETR '+name,func)

        if getsize('E:\\PDF\\DOWNS\\'+name)==ftp_dt.size(name):
            print '   OK !  Download of complete  '+repr(name)+'  SUCCEEDED'
        else:
            print '   FAILURE !! :  '+name+'  only partially downloaded'
else:
    print '\nThere is no PDF file in this FTP directory'


ftp_dt.quit()
ftp_pi.quit()

这里定义了两个连接 ftp_dtftp_pi,分别用于“数据传输”和“协议解释”,因为 FTP 协议是基于两个通道的,一个用来发送命令,另一个用来……你猜是什么?

func() 这个函数在 retrbinary() 函数中作为回调函数使用。

其实可以简单写成

def func(content):
    f.write()

不过我稍微玩了一下函数默认变量的可能性。

有一点我不太明白:为什么这段代码能工作,而在 func() 中的引用 f 只是在 func() 定义之后的代码文本中才有的。但我测试过了,它确实能工作!

撰写回答