Python:ftplibでアップロード中に[WinError 10013]で中断してしまう

- Python -
2020.02.20
Python[パイソン]

Windows10端末からMixhostのサーバ上に画像を大量一括アップロードする必要があり、Pythonのftplibモジュールを使って片付けようと思いました。

ところが、何度やっても画像170枚目あたりで

....
File "...\Python\Python36-32\lib\ssl.py", line 871, in read
return self._sslobj.read(len, buffer)
File "...\Python\Python36-32\lib\ssl.py", line 631, in read
v = self._sslobj.read(len, buffer)
OSError: [WinError 10013] アクセス許可で禁じられた方法でソケットにアクセスしようとしました。

というエラーが発生し、中断されてしまう結果に。

その時の対処法をメモします。

ftplib × [WinError 10013] アクセス許可で禁じられた方法でソケットにアクセスしようとしました。の対処方法

参考までに、自分の書いていたコードの簡易版がこんな感じ。14行目のstorbinary()でエラーが発生していました。

import os
from ftplib import FTP_TLS as FTPS

# リストでファイル名が返る
images = os.listdir(BASE_DIR)

# FTPS接続
ftp = FTPS(host=HOST, user=USER, passwd=PASS)
ftp.prot_p()
ftp.cwd('public/images')

for image in images:
    # ★ここ↓でエラーが発生!!
    ftp.storbinary(f'STOR {image}', open(f'{BASE_DIR}{image}', 'rb'))

print('サーバへファイルのアップロードが完了しました。\n')

これを、

  1. エラー発生元の25行目からtry exceptで囲んで、
  2. エラーが発生したら再接続する用の関数(ftps_reconnect)を実行する

というふうにしたら、中断することなく無事に全てアップロードできるようになりました。

import os
from ftplib import FTP_TLS as FTPS
from time import sleep

# OSErrorが出た時にFTPS再接続する
def ftps_reconnect(ftp):
    try:
        ftp.quit()
    except ConnectionResetError:
        print("Connection was already closed")
    sleep(2)
    ftp = FTPS(host=HOST, user=USER, passwd=PASS)
    ftp.prot_p()
    ftp.cwd('public_html/images')
    return ftp

images = os.listdir(BASE_DIR)

ftp = FTPS(host=HOST, user=USER, passwd=PASS)
ftp.prot_p()
ftp.cwd('public_html/images')

for image in images:
    try:
        ftp.storbinary(f'STOR {image}', open(f'{BASE_DIR}{image}', 'rb'))
    # OSError が出たら、FTPSコネクションを再接続する
    except OSError as e:
        ftp = ftps_reconnect(ftp)
        ftp.storbinary(f'STOR {image}', open(f'{BASE_DIR}{image}', 'rb'))

print('サーバへファイルのアップロードが完了しました。\n')

参考stack overflow:Python ftplib OSError: [WinError 10013] on STOR operation