回答編集履歴

1

修正

2018/05/30 07:25

投稿

can110
can110

スコア38262

test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [ftplib](https://github.com/python/cpython/blob/master/Lib/ftplib.py)ソースの[このあたり](https://github.com/python/cpython/blob/master/Lib/ftplib.py#L106)や[このあたり](https://github.com/python/cpython/blob/master/Lib/ftplib.py#L469)を見るからに、`.nlst`の結果を`Latin-1`(` ISO-8859-1`)として読み込んでいるのが問題のようです。
6
6
 
7
- サーバの返すテキストのエンコーディングと、読込用に開いているテキストのエンコーディングが正しくマッチしていないため、読込後の文字列(`str`型)の内容が正しくりません。
7
+ サーバの返すテキストのエンコーディングと、読込用に開いているテキストのエンコーディングが正しくマッチしていない場合、読込後の文字列(`str`型)の内容が正しくりません。
8
8
 
9
9
 
10
10
 
@@ -16,26 +16,76 @@
16
16
 
17
17
 
18
18
 
19
+ ## 修正
20
+
21
+ サーバ側が対応しているかによりますが、`OPTS UTF8 ON`コマンドによって、サーバ応答を`UTF-8`エンコーディング指定できるかもしれません。指定できた場合は`ftp.encoding = 'utf-8'`により`utf-8`で受け取れます。
22
+
23
+
24
+
25
+ 以下、検証コードです。
26
+
19
- ちなみに`IIS(10.0)`だと`shift_jis`正常読み込めるようになりました
27
+ 当方環境の`IIS(10.0)`や、著名FTPサイトはこのコマンド対応しているようです
20
28
 
21
29
  ```Python
22
30
 
23
- from ftplib import FTP
31
+ from ftplib import FTP, all_errors
24
32
 
25
- with FTP('localhost') as ftp:
26
33
 
27
- ftp.encoding = 'shift_jis' # この行を追加
28
34
 
29
- ftp.login()
35
+ host_names = [
30
36
 
31
- items = ftp.nlst('test/')
37
+ #'localhost', # 独自検証できるサーバがあれば…
32
38
 
33
- with open('ret.txt', 'w', encoding='utf-8') as f:
39
+ 'ftp.riken.go.jp','ftp.jaist.ac.jp','ftp.u-aizu.ac.jp','ftp.iij.ad.jp','ftp.mirrorservice.org' # 著名サイト
34
40
 
35
- for row in items:
41
+ ]
36
42
 
37
- f.write(row + '\n') # 標準出力に惑わされないようファイルにも出力
38
43
 
44
+
45
+ with open( 'nlst.txt', 'w', encoding='utf-8') as f:
46
+
47
+
48
+
49
+ for host_name in host_names:
50
+
51
+ with FTP(host_name) as ftp:
52
+
53
+ print(host_name)
54
+
55
+ f.write(host_name + '\n')
56
+
57
+
58
+
59
+ # まずはサーバ側にUTF-8で応答してもらうように頼む
60
+
61
+ try:
62
+
63
+ print(ftp.sendcmd('OPTS UTF8 ON')) # 確認用
64
+
65
+
66
+
67
+ ftp.voidcmd( 'OPTS UTF8 ON')
68
+
69
+ ftp.encoding = 'utf-8'
70
+
71
+ except all_errors as e:
72
+
73
+ print( e)
74
+
75
+ # 'Latin-1'以外のサーバが利用している(と思われる)エンコーディングが分かっていれば指定する
76
+
39
- print(row) # test/あいう_sjis.txt
77
+ ftp.encoding = 'shift_jis'
78
+
79
+
80
+
81
+ ftp.login()
82
+
83
+ items = ftp.nlst('pub/')
84
+
85
+ for row in items:
86
+
87
+ f.write(row + '\n') # 標準出力に惑わされないようファイルにも出力
88
+
89
+ print(row)
40
90
 
41
91
  ```