我一直使用非常简单的批处理文件从UNIX ftp服务器上下载数百万个文件
login
passwd
ascii
prompt n
cd to the right directory
get some_file
get another_file
cd to the next directory
repeat the pattern
关于这个的好处是它很简单,并且所有文件都使用Window的换行符到达,因此文件已准备好与我现有的程序一起使用。由于我的路由器发生了一些变化,我不得不编写一个Python脚本来提取文件 - 我的第一个版本的脚本非常简单 - 但它可以正常工作
for key in key_filings:
for filing in key_filings[key]:
remote_directory = '/foo/bar/' + key + '/' + filing['key_number']
ftp.cwd(remote_directory)
text_file = filing['txt']
ftp.retrlines('RETR '+ text_file, open(save_dir + text_file,'w').writelines)
hdr_file = filing['hdr']
ftp.retrlines('RETR ' + hdr_file, open(save_dir + hdr_file,'w').writelines)
但是,文件没有任何明显的换行符。这些文件存储在unix系统中。在我使用Windows CMD shell下载文件之前,换行符就在那里。我已经尝试发送ASCII命令,但正如预期的那样没有任何影响。
至关重要的是,我能够访问最初存在的换行符,因为我的一些代码处理是基于行的。
答案 0 :(得分:6)
通常情况下,当我写出问题时,我可以找到答案。我想删除问题而不是回答问题,但我认为可能有其他像我这样的人可以使用答案,所以我将发布Fredrik Lundh从webpage发布的内容。
我想保存文件,而不是像在脚本中那样将其打印到屏幕上
基本上,后退是从服务器一次检索一行(在下面的脚本中我正在写行,因为它在到达时添加了换行符。
我真的不了解lamda函数或回调是什么,所以这是最终围绕这些概念的借口。
import ftplib
ftp = ftplib.FTP('ftp.some.site', user = 'username', passwd = 'password_for_username')
for key in key_filings:
for filing in key_filings[key]:
remote_directory = '/foo/bar/' + key + '/' + filing['key_number']
ftp.cwd(remote_directory)
text_file = filing['txt']
save_text_ref = open(save_dir + text_file, 'w')
ftp.retrlines('RETR '+ text_file, lambda s, w = save_text_ref.write: w(s+'\n'))
save_text_ref.close()
hdr_file = filing['hdr']
save_hdr_ref = open(save_dir +hdr_file,'w')
ftp.retrlines('RETR ' + hdr_file, lambda s, w = save_hdr_ref.write: w(s+'\n'))
save_hdr_ref.close()
答案 1 :(得分:3)
爱PyNEwbie使用lambda,谢谢。以下是相同代码的更通用版本 - 尝试将此作为评论添加到您的帖子中,但不会占用代码:
from ftplib import FTP
def ftp_download_textfile(host, user, passwd, subdir, filename):
ftp = FTP(host, user=user, passwd=passwd)
ftp.cwd(subdir)
fp = open(filename, 'w')
ftp.retrlines('RETR ' + filename, lambda s, w = fp.write: w(s + '\n'))
fp.close()
ftp_download_textfile('ftp.example.com', 'skywalker', 'maltesefalcon',
'spec/files', 'secretplans.csv')
答案 2 :(得分:0)
我正在看这个,并想知道为什么ftplib的创建者决定首先删除新的行字符。我用Google搜索并没有找到满意的答案,所以我想知道进入ftplib并更改代码 - 这对我来说似乎更简单,然后是我的第一个答案。因此我在C:\ Python27 \ Lib
中找到了ftplib.py文件我制作了一份名为ftplib_myMOD.py的副本,然后在IDLE中打开它。并找到了后退功能并对其进行了修改
fp = conn.makefile('rb')
while 1:
line = fp.readline()
if self.debugging > 2: print '*retr*', repr(line)
if not line:
break
#if line[-2:] == CRLF: Commented out
# line = line[:-2] Commented out
#elif line[-1:] == '\n': Commented out
# line = line[:-1] commented out
保存文件,关闭IDLE并重新启动它。执行此操作并导入后
import ftplib_MYMOD as myftp
我发现线条断裂存在。
我喜欢这种方法,因为这意味着我使用的步骤比使用lambda时少。不确定它是否是完全好的做法,但通过查看函数并从中学习一些东西很有趣。
答案 3 :(得分:0)
为什么CRLF被剥夺真是太奇怪了。我在IBM iSeries DB2上尝试过。最终这样做是为了避免每次读取的行都对磁盘文件进行I / O。
lines = []
ftp.retrlines('RETR ' + remote_file, lambda d:lines.append(d+'\n'))
f=open(yourfile,'w')
f.writelines(lines)
f.close()