Загрузка каталогов сайта

zagruzka katalogov sajta Сценарии на стороне клиента

Следующие два сценария призваны удовлетворить эту потребность. Первый из них, downloadflat.py, автоматически загружает (то есть копирует) по FTP все файлы из каталога удаленного сайта в каталог на локальном компьютере. В настоящее время я храню основные копии файлов моего сайта на своем ПК, но в действительности использую этот сценарий двумя способами:

На самом деле это не совсем так. Во втором издании книги в этом месте приводился горестный рассказ о том, как мой провайдер вынудил своих пользователей отучиться от доступа по Telnet. В настоящее время это уже не кажется такой большой проблемой. Обычная практика в Интернете, получившая широкое распространение в короткие сроки. Один из моих сайтов даже вырос настолько, что его стало слишком сложно редактировать вручную (конечно, кроме случаев, когда это обусловлено необходимостью обхода ошибок в инструменте конструирования сайтов). Только вдумайтесь, что значит присутствие Python в Веб. А ведь когда я впервые столкнулся с Python в 1992 году, это был набор кодированных сообщений электронной почты, которые пользователи декодировали, объединяли и уповали, что полученный результат будет работать. «Да, да, понимаю — давай, дед, расскажи еще…»

     Чтобы загрузить мой веб-сайт на клиентский компьютер, где я хочу заняться редактированием, я загружаю содержимое веб-каталога своей учетной записи на сервере моего интернет-провайдера.

     Чтобы сделать зеркальную копию моего сайта на другом сервере, я периодически выполняю этот сценарий на целевом компьютере, если он поддерживает Telnet или безопасную оболочку SSH — в противном случае я просто загружаю файлы веб-сервера на один компьютер и выгружаю их оттуда на требуемый сервер.

Вообще говоря, этот сценарий (представленный в примере 13.10) загрузит полный каталог файлов на любой компьютер с Python и сокетами с любого компьютера, на котором работает сервер FTP.

Пример 13.10. PP4E\Internet\Ftp\Mirror\downloadflat.py

#!/bin/env python """

############################################################################ использует протокол FTP для копирования (загрузки) всех файлов из единственного каталога на удаленном сайте в каталог на локальном компьютере; запускайте этот сценарий периодически для создания зеркала плоского каталога FTP-сайта, находящегося на сервере вашего провайдера; для анонимного доступа установите переменную remoteuser в значение anonymous‘; чтобы пропускать ошибки загрузки файлов, можно было бы использовать инструкцию try, но в случае таких ошибок FTP-соединение скорее всего все равно будет закрыто автоматически; можно было бы перед передачей каждого нового файла переустанавливать соединение, создавая новый экземпляр класса FTP: сейчас устанавливается всего одно соединение; в случае неудачи попробуйте записать в переменную nonpassive значение True, чтобы использовать активный режим FTP, или отключите брандмауэр; кроме того, работоспособность этого сценария зависит от настроек сервера FTP и возможных ограничений на загрузку.

############################################################################

import os, sys, ftplib

from getpass import getpass

from mimetypes import guess_type

nonpassive = False # в 2.1+ по умолчанию пассивный режим FTP

remotesite = ‘home.rmi.net’ # загрузить с этого сайта

remotedir = ‘.’ # и из этого каталога (например, public_html)

remoteuser = ‘lutz’

remotepass = getpass(‘Password for %s on %s: ‘ % (remoteuser, remotesite)) localdir = (len(sys.argv) > 1 and sys.argv[1]) or ‘.’

cleanall = input(‘Clean local directory first? ‘)[:1] in [‘y’, ‘Y’]

print(‘connecting…’)

connection = ftplib.FTP(remotesite) # соединиться с FTPсайтом

connection.login(remoteuser, remotepass) # зарегистрироваться

#  с именем/паролем

connection.cwd(remotedir) # перейти в копируемый каталог

if nonpassive: # принудительный переход

#   в активный режим FTP

connection.set_pasv(False) # большинство серверов работают

#   в пассивном режиме

if cleanall: # сначала удалить все локальные

for localname in os.listdir(localdir): # файлы, чтобы избавиться от

try: # устаревших копий os.listdir

print(‘deleting local’, localname) # пропускает . и ..

os.remove(os.path.join(localdir, localname))

except:

print(‘cannot delete local’, localname)

count = 0 # загрузить все файлы из удаленного каталога

remotefiles = connection.nlst() # nlst() возвращает список файлов

# dir() возвращает полный список

for remotename in remotefiles:

if remotename in (‘.’, ‘..’): continue # некоторые серверы

# включают . и ..

mimetype, encoding = guess_type(remotename) # например,

# (‘text/plain’,’gzip’) mimetype = mimetype or ‘?/?’ # допускается (None, None)

maintype = mimetype.split(‘/’)[0] # .jpg (‘image/jpeg’, None’)

localpath = os.path.join(localdir, remotename) print(‘downloading’, remotename, ‘to’, localpath, end=’ ‘) print(‘as’, maintype, encoding or »)

if maintype == ‘text’ and encoding == None:

#   использовать текстовый файл и режим передачи ascii

#   использовать кодировку, совместимую с ftplib

localfile = open(localpath, ‘w’, encoding=connection.encoding) callback = lambda line: localfile.write(line + ‘\n’) connection.retrlines(‘RETR ‘ + remotename, callback)

else:

#   использовать двоичный файл и двоичный режим предачи localfile = open(localpath, ‘wb‘)

connection.retrbinary(‘RETR ‘ + remotename, localfile.write)

localfile.close() count += 1

connection.quit()

print(‘Done:’, count, ‘files downloaded.’)

В этом примере не так много нового для обсуждения в сравнении с примерами использования протокола FTP, которые мы видели выше. Здесь мы открываем соединение с удаленным сервером FTP, регистрируемся с необходимыми именем пользователя и паролем (в этом сценарии не используется анонимный доступ к FTP) и переходим в требуемый удаленный каталог. Новыми здесь, однако, являются циклы обхода всех файлов в локальном и удаленном каталогах, загрузка в текстовом режиме и удаление файлов:

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий