1

私は何年もの間、非常に単純なバッチ ファイルを使用して、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 シェルを使用してファイルをダウンロードする前は、改行がそこにありました。ASCII コマンドを送信しようとしましたが、予想どおり、何の効果もありませんでした。

私のコード処理の一部は行ベースであるため、元々存在していた改行にアクセスできることが重要です。

4

4 に答える 4

6

質問を書き出すとよくあることですが、答えを見つけに行くことができます。回答する代わりに質問を削除することを考えましたが、回答を使用できる私のような他の人がおそらくいると思うので、Fredrik LundhのこのWeb ページから抜粋したものを投稿します。

そのスクリプトで行われたように、ファイルを画面に出力する代わりにファイルを保存したい

基本的に、retrlines はサーバーから一度に 1 行を取得しています (以下のスクリプトでは、改行文字を追加して到着した行を書いています。

ラムダ関数やコールバックとは何かをよく理解していないので、最終的にこれらの概念に頭を悩ませる言い訳です。

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()
于 2013-01-08T22:16:38.147 に答える
3

PyNEwbie のラムダの使い方が気に入りました。ありがとうございます。これは同じコードのより一般的なバージョンです - これをコメントとして投稿に追加しようとしましたが、コードは必要ありません:

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')
于 2016-04-13T14:25:54.463 に答える
0

私はこれを見て、ftplib の作成者が最初に改行文字を取り除くことにした理由を知りませんでした。私はグーグルで検索しましたが、満足のいく答えが見つからなかったので、ftplib に入ってコードを変更することを考えました - これは私の最初の答えよりも簡単に思えました。したがって、 C:\Python27\Lib に ftplib.py ファイルが見つかりました

ftplib_myMOD.py という名前のコピーを作成し、IDLE で開きました。そしてretrlines関数を見つけて修正しました

    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

改行が存在することがわかりました。

ラムダを使用する場合よりも手順が少なくなるため、このアプローチが気に入っています。正確に良い習慣かどうかはわかりませんが、関数を調べて、そこから何かを学ぶのは興味深いことでした。

于 2013-01-08T23:54:38.660 に答える