我正在尝试使用Python的ftplib读取文件而不编写它们。大致相当于:
def get_page(url): try: return urllib.urlopen(url).read() except: return ""
但使用FTP。
我试过了:
def get_page(path): try: ftp = FTP('ftp.site.com', 'anonymous', 'passwd') return ftp.retrbinary('RETR '+path, open('page').read()) except: return ''
但这不起作用。文档中的唯一示例涉及使用该ftp.retrbinary('RETR README', open('README', 'wb').write)格式编写文件。是否可以在不先写入的情况下读取ftp文件?
ftp.retrbinary('RETR README', open('README', 'wb').write)
好吧,您的答案就在眼前:retrbinary方法接受对函数的引用作为第二个参数,该函数在从ftp连接中检索文件内容时被调用。
这是一个简单的示例:
#!/usr/bin/env python from ftplib import FTP def writeFunc(s): print "Read: " + s ftp = FTP('ftp.kernel.org') ftp.login() ftp.retrbinary('RETR /pub/README_ABOUT_BZ2_FILES', writeFunc)
您应该实现writeFunc,以便它实际上将读取的数据附加到内部变量(类似这样),该内部变量使用可调用对象:
#!/usr/bin/env python from ftplib import FTP class Reader: def __init__(self): self.data = "" def __call__(self,s): self.data += s ftp = FTP('ftp.kernel.org') ftp.login() r = Reader() ftp.retrbinary('RETR /pub/README_ABOUT_BZ2_FILES', r) print r.data
更新: 我意识到Python标准库中有一个用于此类事情的模块StringIO:
#!/usr/bin/env python from ftplib import FTP from io import StringIO ftp = FTP('ftp.kernel.org') ftp.login() r = StringIO() ftp.retrbinary('RETR /pub/README_ABOUT_BZ2_FILES', r.write) print r.getvalue()
更新2: StringIO已转入io。结合@TimRichardson的评论。: