Следующий листинг демонстрирует, как с помощью этого сценария запускается удаленная программа. Как и прежде, если не указать имя локального файла явным образом, сценарий выделит базовое имя файла из аргумента с именем удаленного файла. Это не всегда просто или уместно при запуске программ — имя файла может содержать путь к удаленному каталогу в начале и параметры, необходимые для запуска удаленной программы, в конце.
Если при запуске сценарию был передан адрес URL и не было явно указано имя выходного файла, этот сценарий извлечет содержащееся в середине базовое имя файла, применяя сначала стандартный модуль urllib.parse для получения пути к файлу, а затем функцию os.path.split для отделения пути к каталогу. Однако в результате получается имя удаленного сценария, которое может оказаться непригодным для локального сохранения данных. Так, в первом примере запуска сценария, приведенном ниже, его вывод попадает в локальный файл с именем languages.py, полученным как имя сценария в середине URL; во втором примере запуска имя файла указано явно, как CxxSyntax.html, что подавляет извлечение имени файла из URL:
C:\…\PP4E\Internet\Other> python http-getfile-urllib2.py localhost /cgi-bin/languages.py?language=Scheme http://localhost/cgi-bin/languages.py?language=Scheme languages.py b'<TITLE>Languages</TITLE>\n’
b'<H1>Syntax</H1><HR>\n’ b'<H3>Scheme</H3><P><PRE>\n’ b’ (display "Hello World") (newline) \n’ b'</PRE></P><BR>\n’
b'<HR>\n’
C:\…\PP4E\Internet\Other> python http-getfile-urllib2.py localhost /cgi-bin/languages.py?language=C++ CxxSyntax.html http://localhost/cgi-bin/languages.py?language=C++ CxxSyntax.html b'<TITLE>Languages</TITLE>\n’ b'<H1>Syntax</H1><HR>\n’ b'<H3>C </H3><P><PRE>\n’
b"Sorry—I don’t know that language\n" b'</PRE></P><BR>\n’
b‘<HR>\n‘
Здесь удаленный сценарий возвращает сообщение о неудаче поиска, когда в последней команде ему передается строка «C++». Дело в том, что символ «+»в строках URL имеет специальное значение (обозначает пробел), и для надежности оба написанные нами сценария urllib должны были бы пропустить строку filename через такую штуку, как urllib. parse.quote — средство экранирования специальных символов для передачи. Подробно мы будем говорить об этом в главе 15, поэтому считайте это лишь предварительным рассмотрением. Но чтобы заставить работать эту программу, в создаваемой строке URL необходимо использовать специальные последовательности. Ниже показано, как это сделать вручную:
C:\…\PP4E\Internet\Other> python http—getfile—urllib2.py localhost
/cgi-bin/languages.py?language=C%2b%2b CxxSyntax.html
http://localhost/cgi-bin/languages.py?language=C%2b%2b CxxSyntax.html b'<TITLE>Languages</TITLE>\n’
b'<H1>Syntax</H1><HR>\n’ b'<H3>C++</H3><P><PRE>\n’ b’ cout << "Hello World" << endl; \n’ b'</PRE></P><BR>\n’
b‘<HR>\n‘
Кажущиеся странными строки %2b в этой команде вполне объяснимы: как выглядит результат экранирования, требуемого для URL, можно увидеть, запустив вручную стандартные инструменты Python; это то, что данные сценарии должны делать автоматически, чтобы корректно обрабатывать все возможные случаи. Экранирование можно при необходимости отменить с помощью функции urllib.parse.unquote:
C:\…\PP4E\Internet\Other> python
>>> import urllib.parse
>>> urllib.parse.quote(‘C++’)
‘c%2B%2B‘
Опять же не усердствуйте, пытаясь понять несколько последних команд, — мы вернемся к адресам URL и экранированию специальных символов в них в главе 15, когда будем изучать сценарии Python, выполняемые на сервере. Там я также объясню, почему результат для C++ был возвращен со странными символами < < — экранированными последовательностями HTML для <<, сгенерированными вызовом функции cgi.escape в серверном сценарии, который произвел ответ. Обратное преобразование обычно выполняется с помощью инструментов анализа разметки HTML, включая модуль html.parser в библиотеке Python, с которым мы встретимся в главе 19:
>>> import cgi
>>> cgi.escape(‘<<‘)
‘<<’
Кроме того, в главе 15 мы встретимся с поддержкой про кси-серверов и cookie в пакете urllib на стороне клиента. В главе 16 мы обсудим родственные концепции HTTPS — передачу данных по протоколу HTTP через защищенные сокеты, поддерживаемую модулем urllib.request на стороне клиента, если Python был скомпилирован с поддержкой SSL. А теперь пришло время завершить наш обзор Всемирной паутины и Интернета в целом со стороны клиента.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011