質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
FTP

FTP(File Transfer Protocol)は、ネットワークでのファイル転送を行うための通信プロトコルの1つである。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2828閲覧

Python でFTP領域のファイル一覧リストの日本語表示

M25605301621

総合スコア9

FTP

FTP(File Transfer Protocol)は、ネットワークでのファイル転送を行うための通信プロトコルの1つである。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/05/30 01:29

ftpのファイル一覧リストの日本語表示

ftp内のファイル一覧を手軽に取得できるツールを作ろうとしているのですが、
日本語を含むファイル名の取得結果が文字化けしてしまいます。

取得した文字列をencode('shift-JIS')やencode('UTF-8')かけてみると、
エラーメッセージが表示されます。
なんとかファイルの日本語名までprintできないものでしょうか。
どうかご教示ください。

発生している問題・エラーメッセージ

UnicodeEncodeError 'euc-jp' codec can't encode charavtor '/x91' in position 6: ille... ('shift-JIS'も同様)

該当のソースコード

Python

1from ftplib import FTP 2_myFtp =FTP('address','user','pass') 3items = _myFtp.nlst('dir1/dir2/dir3/dir4/') 4for row in items : 5 print(row.encode('euc-jp')) 6print('end') 7_myFtp.quit()

試したこと

row.replace('x91','')
↑エラーに変化なし

補足情報(FW/ツールのバージョンなど)

Pythonistaを使用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2018/05/30 05:13

rowの型はなんでしょう?つまりprint(type(row))とやると何が表示されますか?
M25605301621

2018/05/30 06:08

<class 'str'>と返ってきました!といいますか、型確認の方法自体知りませんでした。ありがとうございます。
guest

回答1

0

ベストアンサー

そもそもFTPにおいて日本語を含むファイル名を使うのは避けるべきなのですが…

ftplibソースのこのあたりこのあたりを見るからに、.nlstの結果をLatin-1( ISO-8859-1)として読み込んでいるのが問題のようです。
サーバの返すテキストのエンコーディングと、読込用に開いているテキストのエンコーディングが正しくマッチしていない場合、読込後の文字列(str型)の内容が正しくなりません。

そこでFTPサーバの返す文字列のエンコーディングを事前に確認しておき、ソース上で明示的に指定することで正しく動作する可能性があります。

参考:Python: Reading Ftp file list with UTF-8?

修正

サーバ側が対応しているかによりますが、OPTS UTF8 ONコマンドによって、サーバ応答をUTF-8エンコーディング指定できるかもしれません。指定できた場合はftp.encoding = 'utf-8'によりutf-8で受け取れます。

以下、検証コードです。
当方環境のIIS(10.0)や、著名FTPサイトではこのコマンドに対応しているようです。

Python

1from ftplib import FTP, all_errors 2 3host_names = [ 4 #'localhost', # 独自検証できるサーバがあれば… 5 'ftp.riken.go.jp','ftp.jaist.ac.jp','ftp.u-aizu.ac.jp','ftp.iij.ad.jp','ftp.mirrorservice.org' # 著名サイト 6 ] 7 8with open( 'nlst.txt', 'w', encoding='utf-8') as f: 9 10 for host_name in host_names: 11 with FTP(host_name) as ftp: 12 print(host_name) 13 f.write(host_name + '\n') 14 15 # まずはサーバ側にUTF-8で応答してもらうように頼む 16 try: 17 print(ftp.sendcmd('OPTS UTF8 ON')) # 確認用 18 19 ftp.voidcmd( 'OPTS UTF8 ON') 20 ftp.encoding = 'utf-8' 21 except all_errors as e: 22 print( e) 23 # 'Latin-1'以外のサーバが利用している(と思われる)エンコーディングが分かっていれば指定する 24 ftp.encoding = 'shift_jis' 25 26 ftp.login() 27 items = ftp.nlst('pub/') 28 for row in items: 29 f.write(row + '\n') # 標準出力に惑わされないようファイルにも出力 30 print(row)

投稿2018/05/30 05:52

編集2018/05/30 07:25
can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

M25605301621

2018/05/30 06:10

ご回答ありがとうございます。いただいた情報をもとに改修して、またコメント致します。
M25605301621

2018/05/30 07:21

↓ご指南いただいた1行で解決しました。 ftp.encoding = 'shift_jis' # この行を追加 取得したファイル名群ではなく、ftplibのインスタンス側にエンコーティングを指定することで うまく動作した、と理解しています。 日本語ファイル名は確かに不適切と思います。このコードを発展させてツールとして機能できるよう試行してみます。ありがとうございました。
can110

2018/05/30 07:27

> ftplibのインスタンス側にエンコーティングを指定する はい。その理解で正しいです。 なお「OPTS UTF8 ON」コマンドによる対処法について追記しました。 サーバー側が対応しているかによりますが、UTF-8で受け取れると、後の処理が楽になります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問