Используйте pdfplumber и Paramiko для чтения PDF-файла с SFTP-сервера - PullRequest
1 голос
/ 27 мая 2020

У меня есть прямое соединение с SFTP-сервером - соединение работает без проблем, и я могу отображать файлы из выбранного каталога без каких-либо серьезных проблем. На сервере есть разные файлы, у меня есть несколько функций для их чтения, и ниже приведен фрагмент кода, касающийся файлов .pdf - я использую pdfplumber для чтения файлов PDF:

# SSH.connect configuration

sftp = ssh.open_sftp()

path = "/server_path/.."
for filename in sftp.listdir(path):
    fullpath = path + "/" + filename
    if filename.endswith('.pdf'):
        #fullpath - full server path with filename - like /server_path/../file.pdf
        #filename - filename without path - like file.pdf
        with sftp.open(fullpath, 'rb') as fl:
            pdf = pdfplumber.open(fl)

в этом for l oop Я хочу прочитать все .pdf файлы в выбранном каталоге - и это работает для меня на локальном хосте без каких-либо проблем.

Я пытался решить это таким образом with sftp.open(path, 'rb') as fl: - но в этом случае это решение не работает и появляется такой код ошибки:

Traceback (most recent call last):
pdf = pdfplumber.open(fl)
return cls(open(path, "rb"), **kwargs)
TypeError: expected str, bytes or os.PathLike object, not SFTPFile

pdfplumber.open принимает в качестве аргумента точный путь к файлу с его именем - в данном случае полный путь. Как я могу решить эту проблему, чтобы она работала напрямую с сервера? Как управлять памятью в этом случае - потому что я понимаю, что эти файлы как-то в память втягиваются. Пожалуйста, дайте мне несколько подсказок.

1 Ответ

1 голос
/ 28 мая 2020

Paramiko SFTPClient.open возвращает файловый объект.

Чтобы использовать файловый объект с pftplumber, кажется, что вы можете использовать load function :

pdf = pdfplumber.load(fl)

Вы также захотите прочитать это:
Чтение файла, открытого с помощью Python Метод Paramiko SFTPClient.open медленный


Поскольку файловый объект Paramiko, похоже, работает неоптимально в сочетании с функцией pftplumber.load, в качестве обходного пути вы можете вместо этого загрузить файл в память:

flo = BytesIO()
sftp.getfo(fullpath, flo)
flo.seek(0)
pdfplumber.load(flo)

См. Как использовать Paramiko getfo для загрузки файла с SFTP-сервера в память для его обработки

...