mieki256's diary



2023/06/19(月) [n年前の日記]

#1 [python] PythonでFTP関係を処理したい

Python 3.10.10 で、FTP関係の処理をしたい。環境は Windows10 x64 22H2。

Pythonで簡易FTPサーバを立てる :

Pythonを使って簡易FTPサーバを立てたい。pyftpdlib を使えばできるらしい。pip でインストール。
pip install pyftpdlib

_1_ftpserver.py
import pyftpdlib.authorizers
import pyftpdlib.handlers
import pyftpdlib.servers

wwwdir = "D:\\home\\prg\\python\\_test_sample\\ftp\\www"

# 認証ユーザーを作る
authorizer = pyftpdlib.authorizers.DummyAuthorizer()
authorizer.add_user('user', 'password', wwwdir, perm='elradfmw')

# 個々の接続を管理するハンドラーを作る
handler = pyftpdlib.handlers.FTPHandler
handler.authorizer = authorizer

# FTPサーバーを立ち上げる
server = pyftpdlib.servers.FTPServer(("127.0.0.1", 21), handler)
server.serve_forever()

python 1_ftpserver.py を実行すると、FTPサーバのIPアドレスは 127.0.0.1、ユーザ名は user、パスワードは password でFTP接続を受け付けるようになる。

PythonでFTPクライアント処理を行う :

Pythonを使って、FTPサーバに接続してファイルをアップロードしたい。ftplibを使えばできるらしい。このモジュールはおそらく標準で入ってる。たぶん。

_2_ftpclient.py
import os
import ftplib

IP_ADDRESS = "127.0.0.1"
USER = "user"
PASSWORD = "password"

files = [
    ["D:\\home\\prg\\python\\_test_sample\\ftp\\src\\index.html", "/public_html/2_natsu"],
    ["D:\\home\\prg\\python\\_test_sample\\ftp\\src\\b.png", "/public_html/2_natsu"],
]

asciimode_ext = ["html", "htm", "css", "cgi", "pl", "py", "rb", "php", "js"]

try:
    ftp = ftplib.FTP(IP_ADDRESS)
    ftp.set_pasv('true')
    ftp.login(USER, PASSWORD)
    print("# FTP login (%s@%s)" % (USER, IP_ADDRESS))
    print(ftp.getwelcome())

    # get file list
    print(ftp.nlst("."))
    print(ftp.nlst("./public_html"))

    for d in files:
        src, dst = d

        if not os.path.isfile(src):
            print("Error : Not found %s" % src)
            continue
        
        ftp.cwd(dst)
        fn = os.path.basename(src)
        ext = os.path.splitext(src)[1][1:]
        if ext in asciimode_ext:
            print("Upload (Ascii) %s -> %s/%s" % (src, dst, fn))
            # ftp.voidcmd('TYPE A')
            with open(src, "rb") as f:
                ftp.storlines("STOR %s" % fn, f)
        else:
            print("Upload (Binary) %s -> %s/%s" % (src, dst, fn))
            # ftp.voidcmd('TYPE I')
            with open(src, "rb") as f:
                ftp.storbinary("STOR %s" % fn, f)

    ftp.quit()
    # ftp.close()
    print("# FTP close.")

except ftplib.all_errors as e:
    print('FTP Error :', e)

_b.png
_index.html.txt

python 2_ftpclient.py を実行すると、127.0.0.1 に、ユーザ名:user、パスワード:password でFTP接続して、ファイルを2つほどアップロードして終了する。

拡張子の種類によって、アスキーモードで転送するか、バイナリモードで転送するかの処理を分けている。

余談。WindowsのFTPツールを使って自動でアップロード :

Windows10 には標準で ftp.exe が入ってる。一般的には ftp.exe を実行して、コマンドを一つ一つ打ち込んで ―― という使い方が説明されてることが多いけれど、テキストファイルに一連のコマンドを列挙しておいて、そのテキストファイルを渡せば、一括で処理することができる。

以下は、前述の Pythonスクリプトでやっていたことを、ftpのコマンドで列挙した事例。

_ftp_cmd_list.txt
open 127.0.0.1
user
password
cd /public_html/2_natsu
lcd src
ascii
put index.html
binary
put b.png
quit

ftp -s:ファイル名、で実行。
ftp -s:ftp_cmd_list.txt

余談その2。アスキーモードについて :

ftp転送する際は、アスキーモードとバイナリモードの2つがあって、アスキーモードで転送すると改行コードが変化したりするのだけど…。今回、前述の Pythonスクリプトで動作確認してみたら、Windows10 + Pythonで立てた簡易FTPサーバに対してFTPでアップロードした場合、改行コードが変化しなくて悩んでしまった。Windows上で動かしてるから改行コードが変わらない状態が正解なのか、それとも簡易FTPサーバだからそこまで対応していないだけなのか…。

Ubuntu Linux 22.04 LTS がインストールされてるサブPCに、FTPサーバ vsftpd をインストールして動作確認してみたところ、前述の Pythonスクリプトでファイルをアップロードした場合でも、ちゃんと改行コードが変化してることが確認できた。とメモ。

参考ページ :


以上、1 日分です。

過去ログ表示

Prev - 2023/06 - Next
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project