Категория > Новости > Python с абсолютного нуля. Работаем с ОС, изучаем регулярные выражения и функции - «Новости»
Python с абсолютного нуля. Работаем с ОС, изучаем регулярные выражения и функции - «Новости»6-08-2021, 00:00. Автор: Parker |
Переменные, типы данных, условия и циклы[/b] Урок 2: Строки, файлы, исключения и работа с интернетом Первые два урока доступны целиком без платной подписки. Этот — почти целиком: за исключением последнего примера и домашнего задания. Работаем с файламиНачнем, как всегда, с несложных вещей. В Python есть модуль с лаконичным названием Первым делом, конечно, нужно импортировать его в начале нашего скрипта:
import os
И теперь нам открываются разные интересные возможности. К примеру, мы можем получить путь к текущей папке. Сначала она совпадает с той, в которой ты был при запуске скрипта (даже если сам скрипт находится где‑то в другом месте), но по ходу исполнения программы мы можем менять это значение при помощи функции
# Возвращает путь к текущей рабочей папке
pth=os.getcwd()
print(pth)
# Устанавливает путь к текущей рабочей папке, в данном случае это диск D:/
os.chdir(r'D:/')
infoЕсли ты работаешь в Windows, то в пути к файлу или папке перед открывающей кавычкой указывай букву Попробуем получить список файлов с расширением .py, находящихся в текущей директории. Для этого используем модули os и fnmatch.
import os
import fnmatch
# В цикле, с помощью os.listdir('.') получим список файлов
# в текущей директории (точка в скобках как раз ее и обозначает)
for fname in os.listdir('.'):
# Если у текущего имени файла расширение .py, то печатаем его
if fnmatch.fnmatch(fname, '*.py'):
print(fname)
Модуль fnmatch позволяет искать в строках определенный текст, подходящий по маске к заданному шаблону:
Давай безжалостно удалим какой‑нибудь файл: (os.remove(r'D:allmypasswords.txt')) Переименуем файл:
import os
os.rename('lamer.txt','xakep.txt')
А теперь создадим папку по указанному пути и сразу же удалим ее. Для этого пригодится модуль shutil, где есть функция import shutilos.makedirs(r'D:secretbeerphoto') # Создает все папки по указанному путиshutil.rmtree(r'D:secretbeerphoto') # Удаляет папку вместе с ее содержимым Допустим, ты хочешь получить список всех файлов, содержащихся в папках по указанному пути (учитывая вложенные папки тоже), чтобы найти что‑то интересное. Скрипт будет выглядеть следующим образом: warningБудь осторожен — скрипт в таком виде обшарит весь диск D. Если он у тебя есть и там много хлама, то процесс может затянуться.
import os
for root, dirs, files in os.walk(r'D:'):
for name in files:
fullname = os.path.join(root, name)
print(fullname)
if('pass' in fullname):
print('Бинго!!!')
Функция walk() модуля os принимает один обязательный аргумент — имя каталога. Она последовательно проходит все вложенные каталоги и возвращает объект‑генератор, из которого получают:
infoГенератор — это объект, который сразу при создании не вычисляет значения всех своих элементов. Этим генераторы отличаются от списков — те хранят в памяти все свои элементы, и удалить их можно только программно. Вычисления с помощью генераторов называются ленивыми, они экономят память. Подробнее мы рассмотрим генераторы в следующих уроках. Сейчас покажу, как узнать размер любого файла, а также дату его модификации. # Модуль для преобразования даты в приемлемый форматfrom datetime import datetimepath = r'C:Windowsnotepad.exe'# Получим размер файла в байтахsize = os.path.getsize(path)# А теперь в килобайтах# Две косые черты — это целочисленное делениеksize = size // 1024atime = os.path.getatime(path)# Дата последнего доступа в секундах с начала эпохиmtime = os.path.getmtime(path)# Дата последней модификации в секундах с начала эпохиprint ('Размер: ', ksize, ' KB')print ('Дата последнего использования: ', datetime.fromtimestamp(atime))print ('Дата последнего редактирования: ', datetime.fromtimestamp(mtime)) infoДля операционных систем Unix 1 января 1970, 00:00:00 (UTC) — точка отсчета времени, или «начало эпохи». Чаще всего время в компьютере вычисляется в виде прошедших с этого момента секунд и лишь затем переводится в удобный для человека вид. Давай пошутим над юзером: создадим какой‑нибудь файл и будем постоянно его открывать с помощью той программы, которой этот файл обычно открывается в системе:
import os
# Модуль time понадобится для паузы, чтобы не слишком часто открывалось
import time
# Создаем текстовый файл
f=open('beer.txt','w',encoding='UTF-8')
f.write('СРОЧНО НАЛЕЙТЕ ХАКЕРУ ПИВА, ИНАЧЕ ЭТО НЕ ЗАКОНЧИТСЯ!!')
f.close()
while True:
# Открываем файл программой по умолчанию
os.startfile('beer.txt')
# Делаем паузу в одну секунду
time.sleep(1)
Ниже приведен список еще некоторых полезных команд:
Регулярные выраженияРегулярные выражения — это специальные шаблоны для поиска и замены строк в тексте. Вообще говоря, их вполне можно считать самостоятельным языком, и его изучение выходит за рамки этого цикла. Мы пройдемся по самым основам и по использованию регулярок в Python. wwwПодробнее о регэкспах ты можешь почитать в документации Python, в Википедии или в книге Джеффри Фридла, которая так и называется — «Регулярные выражения». Мы не раз писали о полезных сайтах, которые помогают работать с регулярными выражениями: CyberChef, RegExr, txt2re. Помимо этого, можешь обратить внимание на сервис regex101.com и сайт RegexOne с интерактивным тренажером. За работу с регулярными выражениями в Python отвечает модуль re. Первым делом импортируем его.
import re
В качестве простейшего паттерна мы можем использовать какое‑нибудь слово. Пусть по традиции это будет «пиво»:
import re
pattern = r"пиво"
string = "Хакер знает, что пиво играет во взломе решающую роль. Свежее пиво — ключ к сисадмину. Пока сисадмин ходит писать, можно сесть за его комп и внедрить троян."
result = re.search(pattern, string)
print(result.group(0))
Команда Чтобы вернуть все вхождения шаблона в текст, используется команда
import re
pattern = r"пиво"
string = "Хакер знает, что пиво играет во взломе решающую роль. Свежее пиво — ключ к сисадмину. Пока сисадмин ходит писать, можно сесть за его комп и внедрить троян."
result = re.findall(pattern, string)
print(result)
infoОбрати внимание, что шаблоны в регулярных выражениях имеют буковку r перед началом строки. Это так называемые сырые строки, в которых не работает символ экранирования с помощью обратного слеша В предыдущих двух примерах программ в качестве шаблона Давай, например, попробуем найти в тексте все слова, которые начинаются с «пи». Для этого используем специальный символ pattern = r"bпиw+"string = "Хакер знает, что пиво играет во взломе решающую роль. Свежее пиво — ключ к сисадмину. Пока сисадмин ходит писать, можно сесть за его комп и внедрить троян."result = re.findall(pattern, string)print(result) Краткая справка по специальным символамДавай попробуем выполнить чуть более сложную задачу. Найдем в тексте все email с доменом pattern = r"bw+@mail.ru"string = "Если вы хотите связаться с админом, пишите на почту admin@mail.ru. По другим вопросам обращайтесь на support@mail.ru."result = re.findall(pattern, string)print(result) Как видишь, мы использовали тот же трюк, что и в прошлый раз, — написали специальный символ Часто бывает нужно найти какой‑то элемент строки, окруженный двумя другими элементами. Например, это может быть URL. Чтобы выделить ту часть шаблона, которую нужно вернуть, используются скобки. Приведу пример, в котором ты получишь все адреса ссылок из какого‑то кусочка кода на HTML.
import re
string = 'Вы можете посмотреть карту сайта <a href="map.php">тутa>. Посетите также <a href="best.php"разделa>'
pattern = r'href="(.+?)"'
result = re.findall(pattern,string)
print(result)
В коде выше использовался паттерн infoЗнак вопроса в регулярных выражениях используется в двух немного разных смыслах. Если он идет после одного символа, это значит, что символ может присутствовать или не присутствовать в строке. Если же вопросительный знак идет после группы символов, это означает «нежадный» (non-greedy) режим: такая регулярка будет стараться захватить как можно меньше символов. Мы можем не только искать строки, но и заменять их чем‑то другим. Например, давай попробуем удалить из HTML-кода все теги. Для этого используется команда
import re
string = 'Вы можете посмотреть карту сайта <a href="map.php">тутa>. Посетите также <a href="best.php"разделa>'
pattern = r'<(.+?)>'
result = re.sub(pattern,'',string)
print(result)
Программа напечатает строку уже без тегов, так как мы заменили их пустой строкой. Регулярные выражения — очень мощная штука. Освоив их, ты сможешь делать со строками почти все, что угодно, а в сочетании с кодом на Python — буквально что угодно. Для начала же можешь поэкспериментировать и изменить какие‑то из приведенных рецептов. ФункцииПришла пора подробнее поговорить о функциях. Мы уже неоднократно вызывали разные функции — как встроенные в Python (например, Представь, что у тебя есть какой‑то набор команд, которые нужно выполнять несколько раз, изменяя лишь входные данные. Такие блоки команд обычно выносят в отдельные кусочки программы. infoВ объектно ориентированном программировании функции являются методами какого‑либо класса и пишутся через точку от его названия.
s='Hello, xakep!'
print(s) # Функция
s.lower() # Метод
У функции могут быть входные параметры — это одна или несколько переменных, которые пишутся в скобках после имени функции. При вызове функции ты можешь передать ей аргументы для этих параметров. Некоторые из параметров могут быть необязательными или иметь значение по умолчанию — на случай, если его не передадут. Объявление функции начинается с ключевого слова Для примера разберем простейшую функцию, которая будет принимать в качестве аргументов два любых числа и перемножать их, возвращая результат умножения. Назовем ее umn.
def umn(a, b):
c = a * b
return c
Теперь, когда ты описал функцию, далее в этой же программе можно ее вызывать.
a = int(input('Введите первое число: '))
b = int(input('Введите второе число: '))
с = umn(a, b)
print(c)
Иногда надо задать один из параметров как необязательный, установив для него значение по умолчанию.
def umn(a, b=10):
c = a * b
return c
Теперь если ты вызовешь функцию и не передашь ей второй аргумент, то она просто будет считать его равным десяти, то есть будет умножать любое переданное число на десять.
с=umn(5)
print(c)
Несмотря на то что параметр
с=umn(5, b=20)
print(c)
Внутри программы мы можем вызывать созданную нами функцию сколько угодно раз. Давай создадим программу, которая будет считать прибавку к зарплате за каждую уязвимость, которую хакер нашел на работе. У каждого хакера будет своя зарплата, в зависимости от его ранга, но начисление прибавки для всех работает по принципу «+2% к базовой зарплате за уязвимость, если таких уязвимостей найдено больше чем три». Сделаем функцию, которая принимает в качестве аргументов размер зарплаты сотрудника и количество найденных уязвимостей. Для округления результата используем функцию
def pribavka(zarplata, bugs):
k = 0
if bugs > 3:
k = round((bugs - 3) * 0.02 * zarplata)
return k
a = int(input('Введите зарплату сотрудника: '))
b = int(input('Введите количество найденных им уязвимостей за месяц: '))
c = pribavka(a, b)
print('В этом месяце прибавка к зарплате составит: ' + str(c))
Если функция должна возвращать больше одного значения, то можно перечислить их через запятую.
def myfunc(x):
a = x + 1
b = x * 2
return a, b
Функция будет возвращать список, но мы можем сразу присвоить возвращаемые значения каким‑нибудь переменным:
plusone, sum = myfunc(5)
Внутри функций вполне можно использовать переменные, которые встречались в коде программы до вызова функции. Но если внутри кода функции задать переменную с таким же именем, то эта переменная автоматически станет локальной и все дальнейшие изменения будут происходить с ней только в пределах функции. Поясню на примере:
def boom(a, b):
z = 15
c = a * b * z
return c
z = 1
c = boom(15, 20)
print(z)
В результате выполнения программы ты увидишь единицу. Почему? Внутри кода функции мы присвоили переменной Это немного трудно понять, но на самом деле удобно. Если ты пишешь несколько похожих функций, то вполне можешь использовать внутри них одинаковые названия локальных переменных, не опасаясь, что они будут влиять как‑то друг на друга. Переменные, объявленные вне функций, называются глобальными. Если ты хочешь изнутри функции изменить одну из них, то объяви ее внутри функции, использовав ключевое слово
def addfive(num):
global a
a += num
a = 5
addfive(3)
print(a)
Эта программа напечатает 8. Обрати внимание, что мы ничего не возвращали через
a = 5
print(addfive(3))
На экране выведется слово
def isoneortwo(num):
if(num==1):
return 'Один'
if(num==2):
return 'Два'
print(isoneortwo(1))
print(isoneortwo(2))
print(isoneortwo(3))
Эта функция проверяет, равно ли значение единице или двойке, и если не равно, то вернет
if isoneortwo(3) is None:
print("Не 1 и не 2!")
Итак, мы научились создавать функции, вызывать их и возвращать из них параметры, а также использовать внутри функций глобальные переменные. С этого момента мы уже можем браться за относительно сложные примеры! Практика: проверка SQL-уязвимостейНа этот раз мы создадим скрипт, который будет искать SQL-уязвимости по разным URL. Заранее создадим файл
http://www.taanilinna.com/index.php?id=325
https://www.925jewellery.co.uk/productlist.php?Group=3&pr=0
http://www.isbtweb.org/index.php?id=1493
Напишем скрипт, который получает список подобных URL из нашего файла и добавляет в каждый из GET-параметров знак кавычки, пытаясь вызвать ошибки SQL баз данных. Перейти обратно к новости |