От редакции
Недавно мы провели опрос среди читателей и выяснили, что многие хотели бы изучить Python, причем начать с самого начала. В качестве эксперимента мы опубликовали статью «Python с абсолютного нуля. Учимся кодить без скучных книжек», где рассказали об азах Python: переменных, условиях, циклах и списках. Отклики были позитивными, и мы решили продолжить знакомить читателей с Python в нашем фирменном нескучном стиле.
Эта статья, как и предыдущая, доступна без платной подписки, так что смело делись этими ссылками с друзьями, которые мечтают выучить Python!
Начнем со строк. Чтобы решить вставшую перед друзьями проблему, Чебурашка использовал функцию replace(
, которая заменяет в строке одну подстроку другой.
Сначала он объявил переменную s
и поместил туда строку, которую прислал ему Гена.
Дальше Чебурашка определил словарь из слов, которые требовалось заменить.
И теперь при помощи цикла for
Чебурашка перебрал словарь, чтобы заменить каждое из слов (key
) на соответствующее значение из словаря (slova[
):
info
Словари во многом похожи на списки, но значения в них записаны парами: ключ и значение. По ключу можно узнать значение. Можно считать, что в списках ключи — это индексы (0, 1, 2…), а в словарях — строки.
Функцию replace(
удобно использовать, чтобы начисто удалить какие‑то слова из строки. Для этого будем заменять их пустой строкой (если открыть и закрыть кавычку, то получится пустая строка):
info
Чтобы записать в переменную несколько строк, можно обернуть их в три одинарные кавычки и делать переносы прямо в коде.
Чтобы получить количество символов в строке, используется функция len().
И, как я уже рассказывал в прошлой статье, от строк можно брать срезы как от массивов, если указать начало и конец подстроки в квадратных скобках после переменной. Позиция начинается с нуля.
Если нужно сделать срез с начала строки, первую цифру можно не писать.
Предположим, тебе нужно найти в списке строки, которые начинаются на https. Перебираем их с помощью for
, для каждой проверяем, совпадают ли первые пять знаков со строкой https
, и если да, то выводим строку:
Чтобы посчитать количество вхождений подстроки в строку, можно использовать метод .
:
Иногда в начале или в конце строки могут быть лишние пробелы или переносы строк. Давай удалим их специальной командой .
:
info
Переносы строк можно добавить с помощью символов \
(используется во всех ОС) либо \
(в Windows). Есть и другие спецсимволы. Например, \
— знак табуляции.
Чтобы определить наличие подстроки в строке s, можно использовать метод .
:
Если искомая подстрока найдена, то в переменную n
попадет ее позиция в строке, а если не найдена, n
станет равной -1
.
Давай попробуем определить, есть ли в строке адрес электронной почты с Xakep.ru, то есть будем искать подстроку @xakep.
.
Но сначала нам понадобится еще один строковый метод — .
. Он позволяет разделить строку на части, указав в качестве аргумента строку‑разделитель. Например, s.
разделит текст на абзацы по символу переноса строки. Если же оставить скобки пустыми, то будет использован разделитель по умолчанию — пробел.
Метод .
позволяет, наоборот, склеивать строки. Он принимает список и возвращает строку, где каждый элемент списка соединен с другим через строку, у которой ты вызвал этот метод.
Форматируем строки
Мы не раз печатали разные вещи, соединяя строки простым сложением. Это не всегда удобно, особенно учитывая, что если попадутся числа, то их придется переводить в строки функцией str(
. Есть более красивый и удобный способ подставлять значения переменных внутрь строк. Точнее, два немного разных способа.
Способ 1 — c помощью метода .format()
Мы можем вставить в строку парные фигурные скобки, а затем вызвать строковый метод .
и передать ему нужные значения в порядке их подстановки в строку.
Можно передать информацию списком через звездочку:
Способ 2 — через f-строки
Другой вариант — написать букву f
перед строкой и затем в фигурных скобках указывать непосредственно переменные.
Главное преимущество этого способа в том, что ты можешь вставить значение в строку несколько раз. К тому же можно менять значения прямо в фигурных скобках: сперва Python выполнит все действия в них, а затем подставит полученный результат в строку. Так, метод .
в примере выше делает все буквы заглавными.
Файлы
Перечисленных методов достаточно, чтобы ты мог делать со строками что угодно. Но откуда эти строки возьмутся? Чаще всего они записаны в файлах, поэтому сейчас я расскажу, как в Python с ними управляться.
Чтобы работать с файлом, его нужно открыть. Для этого служит функция open(
, а работает она вот так:
Режимов работы с файлами несколько, но тебя интересует в основном:
-
r
— открыть файл для чтения из него информации; -
w
— открыть файл для записи в него информации (создает новый файл); -
a
— открыть файл для дозаписи информации в конец файла (дописывает информацию в конец существующего файла); -
a+
— дозапись и чтение.
Чтобы избежать проблем с путями в Windows, используй в них двойной слеш \
, а также перед открывающей кавычкой пути файла ставь букву u, указывающую на то, что строка в кодировке Unicode:
Читать строки из файла можно методом .
:
Как вариант — можно последовательно читать из файла отдельные строки с помощью цикла for
:
После того как работа с файлом закончена, нужно закрыть его.
info
Для работы с бинарными файлами при открытии файла добавь к режиму букву b
:
Подробнее о бинарных данных мы поговорим в одной из следующих статей.
Давай теперь попробуем создать новый текстовый файл в одном каталоге с нашим скриптом и записать в него значения каких‑то переменных.
Обрати внимание, что в конце каждой строки стоит символ \
— переход на новую строку.
Допустим, ты хочешь дописать третью строчку в конец этого файла. Тут‑то и пригодится режим дозаписи!
Для открытия файлов также очень удобно использовать конструкцию with
, потому что благодаря слову with файл закроется автоматически и тебе не придется думать об этом.
Работа с вебом
Давай научимся получать информацию с веб‑страниц. Для начала нужно установить несколько модулей. Пишем в командной строке:
Модуль requests позволяет делать GET- и POST-запросы к веб‑страницам. Модуль html2text служит для преобразования HTML-кода веб‑страниц в обычный текст, то есть чистит его от тегов HTML.
Импортируем наши новые модули в начале программы и попробуем получить какую‑нибудь страницу из интернета.
Программа напечатает много HTML-кода, из которого состоит главная страница журнала. Но что, если тебе нужен только текст сайта, а не мешанина из тегов? Здесь поможет html2text. Он выделит из кода текст, заголовки и картинки и отдаст их уже без HTML-тегов.
Кроме GET-запросов, существуют так называемые POST-запросы, которые применяются для отсылки на сервер больших текстов или каких‑то файлов. Если видишь на сайте форму, особенно с загрузкой файла, значит, скорее всего, при нажатии на кнопку «Отправить» будет сделан POST-запрос.
Библиотека requests тоже позволяет делать POST-запросы. Тебе это может пригодиться для имитации действий пользователя — например, если нужно автоматизировать работу с сайтом. Можешь даже использовать это в качестве самописного аналога Burp!
Давай посмотрим, как послать обычный POST-запрос. Предположим, на сайте site.
существует скрипт guest.
, который POST-запросом принимает от формы имя пользователя name
и сообщение message
, а затем постит их в гостевую книгу.
Теперь давай отправим запрос с файлом payload.
во вложении и теми же двумя полями формы, что и в предыдущем запросе. Файл придет на сервер под именем misc.
.
Осталось научиться скачивать файлы. Это во многом похоже на запрос страниц, но делать это лучше в потоковом режиме (stream=True
). Также нам понадобится модуль shutil, в котором есть удобная функция copyfileobj
. Она позволяет копировать содержимое двоичных файлов — в нашем случае из интернета к нам на диск.
info
Коды ответа сервера помогают понять, как прошел запрос. Код 200 означает, что сервер успешно обработал запрос и отдал нам ответ, код 404 — страница не была найдена, 500 — внутренняя ошибка сервера, 503 — сервер недоступен и так далее. Полный список кодов ты найдешь в Википедии.
Обработка ошибок
Прежде чем разбирать более реальный пример, я должен показать тебе еще одну языковую конструкцию, которая незаменима при работе с файлами и сетью. Это обработка исключительных ситуаций, то есть ошибок.
Часто при работе программы компьютер сталкивается с разными проблемами. Например, файл не найден, сеть недоступна, кончилось место на диске. Если программист об этом не позаботился, то интерпретатор Python просто завершит работу с ошибкой. Но есть способ предусмотреть неурядицы прямо в коде и продолжать работу — конструкция try...
.
Выглядит она вот так:
Можно ловить конкретные типы ошибок, если после слова except
указать название типа. К примеру, KeyboardInterrupt
срабатывает, если пользователь пытается завершить программу, нажав Ctrl-C. В нашей власти запретить это делать!
Да что там, мы можем даже разрешить делить на ноль, если отловим ошибку ZeroDivisionError
. Вот как это будет выглядеть:
www
Полный список видов исключений
Пишем сканер портов
А теперь мы напишем собственный сканер портов! Он будет простеньким, но вполне рабочим. Поможет нам в этом модуль socket, где реализована работа с сокетами.
info
Cокет — это интерфейс обмена данными между процессами. Существуют клиентские и серверные сокеты. Серверный сокет слушает определенный порт в ожидании подключения клиентов, а клиентский подключается к серверу. После того как было установлено соединение, начинается обмен данными.
Вот как будет выглядеть код.
Как видишь, ничего сложного!
Домашнее задание
-
Сделай, чтобы сканер портов получал список IP из одного файла, а результаты сканирования записывал в другой.
-
В прошлой статье ты научился работать с буфером обмена. Напиши программу, которая постоянно запущена и периодически получает содержимое буфера обмена. Если оно изменилось, то дописывает его в конец файла
monitoring.
Попробуй записывать в лог только те перехваченные строки, в которых есть латинские буквы и цифры, так более вероятно поймать пароли.txt. -
Напиши программу, которая читает файл такого вида:
Иван Иванов|ivanov@mail.ru|Password123Дима Лапушок|superman1993@xakep.ru|1993supermanВася Пупкин|pupok@yandex.ru|qwerty12345Фродо Бэггинс|Frodo@mail.ru|MoRdOr100500Кевин Митник|kevin@xakep.ru|dontcrackitpleaseЮзер Юзерович|uswer@yandex.ru|aaaa321Программа должна сортировать строки по доменам из email, для каждого домена создавать файл и в каждый файл помещать список почтовых адресов.
-
Напиши программу, которая проходит сайты по списку, скачивает файлы robots.txt и sitemap.xml и сохраняет на диск. В случае если файл не найден, выводится сообщение об этом.
На сегодня всё. Из следующей статьи ты узнаешь, как работать с файловой системой ОС, разберешься с функциями, познаешь силу регулярных выражений и напишешь простой сканер SQL-уязвимостей. Не пропусти!