zaLinux.ru

Как в скрипте Python получить данные от веб-страницы методами GET и POST


Программы и скрипты на Python могут делать запросы к веб сайтам и веб сервисам и получать от них данные с помощью методов GET и POST (а также другими HTTP методами: PUT, PATCH и DELETE).

Но что если вы хотите передавать данные из веб-страницы в скрипт Python?

Это можно реализовать несколькими способами.

Как в скрипте Python получить данные от веб-страницы методами GET и POST если Python настроен как CGI модуль веб-сервера

Смотрите также: Как установить Python как CGI модуль в Apache в Linux

В директории веб-сервера создадим подпапку test-python.

В ней создадим HTML файл с именем test-form.htm и следующим содержанием:

<!DOCTYPE html>
    <head>
        <title>ZaLinux.ru: An example of running Python on a web server</title>
    </head>
    <body>

        <form action="program.py" method="post">
            <label for="name">Name:</label>
            <input type="text" id="name" name="name"><br><br>

            <label for="email">Surname:</label>
            <input type="text" id="surname" name="surname"><br><br>

            <label for="message">Information:</label><br>
            <textarea id="info" name="info" rows="4" cols="30"></textarea><br><br>

            <input type="submit" value="Submit">
        </form>

    </body>
</html>

В этой же подпапке создадим файл program.py со следующим содержанием:

#!/usr/bin/python3

# Импорт модулей для обработки CGI
import cgi, cgitb

# Создание экземпляра FieldStorage
form = cgi.FieldStorage()

# Получение данных от полей формы
name = form.getvalue('name')
surname = form.getvalue('surname')
info = form.getvalue('info')

# Вывод HTTP заголовка
print ('Content-type: text/html\r\n\r\n')

# Вывод HTML кода с полученными данными
print ('<html>')
print ('<head>')
print ('<title>ZaLinux.ru: An example of running Python on a web server</title>')
print ('</head>')
print ('<body>')

print ('<em>Python script reports: </em>', '<br /><br />')
print ('<b>Name: </b>', name, '<br />')
print ('<b>Surname: </b>', surname, '<br />')
print ('<b>Extra information: </b>', info, '<br />')

print ('</body>')
print ('</html>')

В комментариях к коду даны пояснения. Для получения данных от формы используется form.getvalue().

Этот файл должен иметь разрешения на выполнение кода:

sudo chmod +x /srv/http/test-python/program.py

Откроем адрес http://localhost/test-python/test-form.htm и заполним данные формы:

Отправим данные на сервер. Как можно убедиться, скрипт Python успешно получил данные из формы, отправленные методом POST на веб-сервер.

Аналогичный код используется для получения данных отправленных методом GET — достаточно изменить метод в строке <form action="program.py" method="get">:

<!DOCTYPE html>
    <head>
        <title>ZaLinux.ru: An example of running Python on a web server</title>
    </head>
    <body>

        <form action="program.py" method="get">
            <label for="name">Name:</label>
            <input type="text" id="name" name="name"><br><br>

            <label for="email">Surname:</label>
            <input type="text" id="surname" name="surname"><br><br>

            <label for="message">Information:</label><br>
            <textarea id="info" name="info" rows="4" cols="30"></textarea><br><br>

            <input type="submit" value="Submit">
        </form>

    </body>
</html>

Обратите внимание, что скрипты Python для использования их с CGI модулем веб-сервера нуждаются в доработке: скрипт должен перед показом данных отсылать HTTP заголовок. Если вы не доработаете скрипт Python, то программа завершится ошибкой.

Полезные ссылки:


Как в скрипте Python получить данные от веб-страницы методами GET и POST если Python не настроен как CGI модуль веб-сервера

В этой части я опишу другой способ передачи данных от веб-страниц методами GET и POST в программу Python. Это решение имеет свои недостатки: требуется наличия PHP. Но при этом у этого способа имеются и преимущества:

  • не требуется подключать Python в качестве модуля веб-сервера Apache. Достаточно того, чтобы Python был установлен в операционной системе
  • не требуется доработка скриптов Python, предусматривающая отправку HTTP заголовков

Краткое описание алгоритма:

  • скрипт PHP получает данные от пользователя через веб-страницу методами GET или POST. Веб-сайт с помощью веб формы отправляет данные на сервер — тривиальная задача
  • этот же самый скрипт PHP с помощью shell_exec запускает скрипт Python, передавая в качестве аргументов командной строки полученные методом GET или POST данные
  • и вновь этот же скрипт PHP дожидается завершения работы программы Python, получает от неё данные и выводит пользователю

В директории веб-сервера создадим подпапку test-python.

В ней создадим HTML файл с именем index.htm и следующим содержанием:


<!DOCTYPE html>
    <head>
        <title>ZaLinux.ru: An example of running Python on a web server</title>
    </head>
    <body>

        <form action="python-connector.php" method="post">
            <label for="name">Name:</label>
            <input type="text" id="name" name="name"><br><br>

            <label for="email">Surname:</label>
            <input type="text" id="surname" name="surname"><br><br>

            <label for="message">Information:</label><br>
            <textarea id="info" name="info" rows="4" cols="30"></textarea><br><br>

            <input type="submit" value="Submit">
        </form>

    </body>
</html>

В этой же подпапке создадим файл python-connector.php со следующим содержанием:

<?php

echo shell_exec ('python /srv/http/test-python/script.py ' . $_POST["name"] . ' ' . $_POST["surname"] . ' '. $_POST["info"]);

Этот файл будет принимать данные от веб формы и запускать скрипт Python.

Также создадим сам файл script.py со следующим содержанием:

import sys

name = sys.argv[1]
surname = sys.argv[2]
if len(sys.argv) < 4:
    info = ''
else:
    info = sys.argv[3]

print ('<html>')
print ('<head>')
print ('<title>ZaLinux.ru: An example of running Python on a web server</title>')
print ('</head>')
print ('<body>')

print ('<em>Python script reports: </em>', '<br /><br />')
print ('<b>Name: </b>', name, '<br />')
print ('<b>Surname: </b>', surname, '<br />')
print ('<b>Extra information: </b>', info, '<br />')

print ('</body>')
print ('</html>')

Файл script.py НЕ обязательно должен быть исполнимым. От файла script.py НЕ требуется выводить HTTP заголовки. Также в файле script.py необязательно указывать шебанг.

Также данный метод не использует модули cgi и cgitb, но использует модуль sys, который нужен для получения аргументов командной строки.

Также обратите внимание, что при такой реализации скрывается тот факт, что сервер использует скрипт Python.

Откроем адрес http://localhost/test-python/ и заполним данные формы:

Отправим данные на сервер. Как можно убедиться, скрипт PHP успешно получил данные из формы, отправленные методом POST на веб-сервер, затем была запущена программа script.py в которую полученные данные отправлены в качестве аргументов командной строки. После завершения работы script.py, вывод этой программы сначала был передан в скрипт PHP и в конечном счёте он был показан пользователю в веб-браузере.


Аналогичный код используется для получения данных отправленных методом GET — достаточно в HTML коде веб -формы изменить метод в строке:

<form action="program.py" method="get">

Рекомендуемые статьи:

4 Комментарии

  1. mikl

    tnx! Пригодилось!
    Только меня немножко мучает вопрос на сколько такой подход безопасен (3 враиант)?

    1. Alexey (Автор записи)

      Приветствую! Вопрос очень правильный — если не фильтровать данные от пользователя, то возможна атака «Внедрение команд ОС».

      Но любые данные от пользователей должны расцениваться как ненадёжные и фильтроваться на специальные символы или другим образом валидироваться (причём обязательно и на стороне сервера, даже если веб-браузер, JavaScript тоже валидируют введённые данные). Если этого не делать, то возможны другие атаки, например, SQL-инъекция, XSS и многие другие.

      Например, без фильтрации данных, все три варианта подвержены XSS, для проверки достаточно в любом из полей добавить

      <script>alert("Pwned")</script>

      То есть данные всегда нужно фильтровать. Здесь — ни в коем случае не рабочие концепты, это просто минимальные обучающие примеры передачи данных из веб-браузера в Python.

  2. mikl

    И как назад передать данные от python к php?

    1. Alexey (Автор записи)

      Приветствую! Данные по умолчанию передаются в программу, которая запустила скрипт. В примере выше возвращённые из Python в PHP данные выводятся с помощью echo:

      echo shell_exec ('python /srv/http/test-python/script.py ' . $_POST["name"] . ' ' . $_POST["surname"] . ' '. $_POST["info"]);

      Вместо вывода их на экран, вы можете присвоить возвращённую из Python строку переменной в PHP:

      $result = shell_exec ('python /srv/http/test-python/script.py ' . $_POST["name"] . ' ' . $_POST["surname"] . ' '. $_POST["info"]);

      То есть вывод скрипта Python будет помещён в переменную PHP с именем $result. Далее можно работать с этой переменной в PHP как с любой другой строкой (парсить данные, сохранять в файл, выводить на экран и прочее).

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *