Введение
В этом проекте вы научитесь создавать простую службу сокращения ссылок с использованием Flask и MySQL. Вы узнаете, как настроить базу данных, спроектировать веб-интерфейс и реализовать функциональность для сокращения ссылок, поиска ссылок по тегам и просмотра аналитики. Проект доступен для начинающих и дает полное представление о веб-разработке на Python и управлении базами данных.
Проект основан на https://github.com/highoncarbs/shorty, который изначально лицензирован под лицензией MIT.
👀 Предпросмотр
Преобразовать ссылку с/без пользовательского суффикса, Поиск ссылок по тегу, Перейти по ссылке:
Просмотреть информацию об операционной системе и платформе, использованной для доступа по ссылке:
🎯 Задачи
В этом проекте вы научитесь:
- Как подключить приложение Flask к базе данных MySQL
- Как создавать и управлять схемой базы данных MySQL для хранения информации о ссылках
- Как реализовать фронтенд-страницы с использованием HTML и CSS для взаимодействия с бэкендом
- Как обрабатывать данные форм и запросы в Flask для создания коротких ссылок
- Как разработать функциональность для перенаправления пользователей из короткой ссылки на исходную ссылку
- Как создать простую функцию аналитики для отслеживания использования ссылок, включая количество кликов и базовую информацию о браузере/платформе
- Как спроектировать удобный для пользователя обработчик ошибок и настраиваемую страницу 404 для улучшения пользовательского опыта
🏆 Достижения
После завершения этого проекта вы сможете:
- Выполнять базовые операции с MySQL, включая создание базы данных и таблиц, вставку данных и запросы
- Разбираться в основах Flask, включая маршрутизацию, обработку запросов и рендеринг шаблонов
- Работать с HTML-формами и обрабатывать данные в приложении Flask
- Применять основные принципы фронтенд-дизайна и использовать CSS для создания визуально привлекательного веб-интерфейса
- Реализовать простую аналитику для сбора и отображения данных о использовании ссылок
- Реализовать лучшие практики обработки ошибок в веб-приложениях для повышения надежности и качества пользовательского опыта
Настройка окружения проекта
Во - первых, нам нужно настроить окружение проекта в терминале. Это включает в себя установку необходимого Python - пакета для подключения к MySQL и запуск службы MySQL. Когда служба запущена, мы создадим базу данных и таблицу для хранения наших ссылок.
Установить PyMySQL:
pip install PyMySQL==1.1.0
Запустить службу MySQL и войти в MySQL - консоль:
sudo service mysql start
mysql -u root
Внутри MySQL - консоли выполните следующие команды для создания базы данных и таблицы:
Создать базу данных:
CREATE DATABASE IF NOT EXISTS SHORTY;
USE SHORTY;
Создать таблицу:
CREATE TABLE IF NOT EXISTS WEB_URL
(
ID INT AUTO_INCREMENT,
URL VARCHAR(512),
S_URL VARCHAR(80),
TAG VARCHAR(80),
COUNTER INT DEFAULT 0,
CHROME INT DEFAULT 0,
FIREFOX INT DEFAULT 0,
SAFARI INT DEFAULT 0,
OTHER_BROWSER INT DEFAULT 0,
ANDROID INT DEFAULT 0,
IOS INT DEFAULT 0,
WINDOWS INT DEFAULT 0,
LINUX INT DEFAULT 0,
MAC INT DEFAULT 0,
OTHER_PLATFORM INT DEFAULT 0,
PRIMARY KEY (ID)
);
Этот SQL - запрос создает таблицу под названием WEB_URL в базе данных SHORTY, предназначенную для хранения информации о сокращенных ссылках и некоторой связанной аналитики.
CREATE TABLE IF NOT EXISTS WEB_URL: Эта команда создает новую таблицу с именемWEB_URLтолько в том случае, если она еще не существует в базе данных. Это помогает избежать ошибок при повторном запуске скрипта.ID INT AUTO_INCREMENT: Этот столбец назначен в качестве первичного ключа таблицы и настроен на автоматическое увеличение с каждым новым записью. Это означает, что каждый раз, когда добавляется новая запись, MySQL автоматически назначает ей уникальный ID, увеличивая его на 1 от предыдущего.URL VARCHAR(512): Этот столбец хранит исходные ссылки, которые сокращаются. Тип данныхVARCHAR(512)означает, что он может хранить строки переменной длины, до 512 символов.S_URL VARCHAR(80): Это столбец для строки сокращенной ссылки, с максимальной длиной 80 символов.TAG VARCHAR(80): Этот столбец предназначен для хранения тегов, связанных с ссылками, для классификации или поиска, с максимальной длиной 80 символов.COUNTER INT DEFAULT 0: Этот целочисленный столбец, вероятно, используется для отслеживания количества раз, которое сокращенная ссылка была посещена. Он по умолчанию равен 0 при создании новой записи. Следующие несколько столбцов предназначены для хранения аналитических данных по сокращенным ссылкам:CHROME,FIREFOX,SAFARI,OTHER_BROWSER: Эти столбцы используются для отслеживания количества посещений с разных веб - браузеров. Каждый из них является целочисленным столбцом, который по умолчанию равен 0.ANDROID,IOS,WINDOWS,LINUX,MAC,OTHER_PLATFORM: Подобно столбцам для браузеров, эти столбцы предназначены для отслеживания посещений с разных операционных систем/платформ, и каждый столбец по умолчанию равен 0.PRIMARY KEY (ID): Эта часть запроса задает, что столбецIDявляется первичным ключом таблицы. Первичный ключ - это уникальный идентификатор каждой записи в таблице, что гарантирует, что у двух записей не будет одинаковыхID.
Такая структура таблицы позволяет хранить, получать и анализировать данные о сокращенных ссылках, включая частоту их посещений, от каких браузеров и от каких операционных систем.
Для выхода из MySQL - консоли можно выполнить следующую команду:
EXIT;
Создать шаблон главной страницы
Главная страница - это то место, где пользователи будут взаимодействовать с сервисом сокращения ссылок. Мы будем использовать HTML и шаблонизатор Flask для создания динамического контента.
В templates/index.html добавьте следующий HTML - код:
<!doctype html>
<html>
<head>
<title>Shorty</title>
<!-- Добавить локальное SVG - изображение при размещении. -->
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js"></script>
<link rel="stylesheet" type="text/css" href="../static/skeleton.css" />
<link rel="stylesheet" type="text/css" href="../static/normalize.css" />
<link rel="stylesheet" type="text/css" href="../static/main.css" />
<link
href="https://fonts.googleapis.com/css?family=Roboto:300,400,700,900"
rel="stylesheet"
/>
</head>
<body>
<div class="container main_header">
<h3 align="left"><a href="{{url_for('index')}}">Shorty</a></h3>
<p>A very simple URL shortening service.</p>
</div>
<div class="u-full-width shorty">
<div class="container"></div>
</div>
</body>
</html>
Вот обзор основных компонентов этого шаблона:
- Google Material Icons: Теги
<link>импортируют библиотеку Google Material Icons, позволяя использовать предопределенные иконки для более привлекательного пользовательского интерфейса. - Clipboard.js: Теги
<script>включают библиотеку Clipboard.js, популярную JavaScript - библиотеку для копирования содержимого в буфер обмена. Это может быть полезно для сервиса сокращения ссылок, позволяя пользователям легко копировать сокращенные ссылки. - Стили: Шаблон ссылается на несколько CSS - файлов для стилизации:
skeleton.css: Легкий CSS - фреймворк, который обеспечивает базовую стилизацию и адаптивную систему сетки.normalize.css: Сбрасывает стандартные стили браузера для обеспечения一致ной стилизации на разных браузерах.main.css: Содержит пользовательские стили, специфичные для сервиса "Shorty".
- Google Fonts: Еще один тег
<link>импортирует семейство шрифтов "Roboto" из Google Fonts, обеспечивая различные веса шрифтов для дизайна типографики. - Внутри
<body>используетсяdivс классомcontainer main_headerдля создания заголовочной секции, которая включает:- Заголовок (
<h3>), содержащий ссылку (<a>), которая перенаправляет на главную страницу, с помощью функцииurl_forFlask, динамически генерирующей URL для маршрута 'index'. - Абзац (
<p>), описывающий сервис как "A very simple URL shortening service."
- Заголовок (
Реализовать сокращение URL-адресов и поиск по тегам
В этом шаге мы усовершенствуем веб - интерфейс, интегрируя две ключевые функции: сокращение ссылок и поиск ссылок по тегам. Это позволит пользователям не только сокращать ссылки, но и эффективно организовывать и получать их с использованием тегов.
Сокращение ссылок
Во - первых, мы создадим форму на главной странице, где пользователи могут ввести ссылку, которую они хотят сократить. Дополнительные поля для пользовательских суффиксов и тегов позволят создавать персонализированные короткие ссылки и классифицировать их для более удобного управления.
Добавьте следующий код в templates/index.html:
<!-- Search URL block -->
<div class="search_url_block">
<form method="post" action="/search" name="search_tag_block">
<input type="text" name="search_url" placeholder="Search tags " />
<button type="submit" class="button-primary search_url_btn" value="Search">
Search
</button>
</form>
</div>
<!-- end block -->
Первый блок кода добавляет форму, предназначенную для поиска ссылок по их связанным тегам:
search_url_block: Этот контейнер содержит поисковую форму, делая ее отдельным разделом на странице для лучшей организации и стилизации.<form>: Определяет форму, которая отправляет POST - запрос на конечную точку/search, когда кнопка поиска нажата. Эта форма имеет имяsearch_tag_blockдля идентификации.<input>: Текстовое поле ввода, где пользователи могут ввести теги, по которым они хотят искать. Атрибутplaceholderдает подсказку пользователю о назначении поля.<button>: Кнопка отправки, которая инициирует отправку формы. Классbutton-primary, вероятно, добавляет специфическую стилизацию, определенную в CSS.
Поиск по тегам
Для дополнения функции сокращения ссылок мы также реализуем функциональность, которая позволяет пользователям искать ссылки по тегам. Эта функция будет интегрирована в шаблон главной страницы, предоставляя простую форму, где пользователи могут ввести теги, чтобы найти соответствующие ссылки.
Добавьте следующий код в templates/index.html:
<!-- URL Input block -->
<form method="post" action="" name="generate_block">
<div class="row">
<input type="text" name="url_input" placeholder="Enter URL" />
<input type="text" name="url_custom" placeholder="Enter Custom Suffix" />
<input type="text" name="url_tag" placeholder="Tag URL" />
<button class="button-primary generate">Generate</button>
</div>
</form>
<!-- end block -->
Второй блок кода представляет форму для пользователей, чтобы сократить ссылки, с дополнительными полями для настройки:
- Весь форма заключается в элемент
<form>сmethod="post"и неуказанным атрибутомaction. Это означает, что данные формы будут отправлены по POST - запросу на текущий URL, когда кнопка "Generate" нажата. - Внутри формы
<div>с классомrowвероятно помогает с макетом и выравниванием, обеспечивая правильную организацию полей ввода и кнопки. - Три элемента
<input type="text">предназначены для разных целей:- Первое поле ввода позволяет пользователям ввести исходную ссылку, которую они хотят сократить.
- Второе позволяет указать необязательный пользовательский суффикс для сокращенной ссылки, позволяя пользователям персонализировать свои короткие ссылки.
- Третье поле предназначено для тегов, позволяя пользователям классифицировать или добавлять описательные метки к своим сокращенным ссылкам для более удобного извлечения и управления.
<button>с классомbutton-primaryи текстом "Generate" служит кнопкой отправки формы. Нажатие этой кнопки отправляет данные на сервер для создания сокращенной ссылки с предоставленной информацией.
Эти улучшения значительно улучшают пользовательский опыт, предоставляя больше функциональности, чем просто сокращение ссылок. Возможность искать ссылки по тегам позволяет эффективно управлять и получать сокращенные ссылки, в то время как возможность добавлять пользовательские суффиксы и теги позволяет персонализировать и классифицировать ссылки. Эта настройка использует HTML - формы для сбора ввода пользователя, который затем будет обработан сервер - сторонним приложением Flask для выполнения требуемых действий.
Обработка ошибок и отображение сокращенных URL-адресов
В этом шаге мы сосредоточимся на улучшении пользовательского опыта путем обработки сообщений об ошибках и отображения сокращенных ссылок.
Обработка ошибок
Во - первых, мы добавим функциональность для отображения сообщений об ошибках пользователям. Это至关重要 для предоставления обратной связи, когда что - то идет не так, например, когда пользователь отправляет недействительную ссылку или тег, который не существует. Корректная обработка ошибок делает приложение более устойчивым и удобным для пользователя.
Добавьте следующий код в templates/index.html:
<!-- Error Display block -->
{% if error!= '' %}
<p class="error_disp">{{error}}</p>
{% endif %} {% if shorty_url %}
<!-- end block-->
Этот блок предназначен для предоставления обратной связи пользователю, если во время процесса сокращения ссылки произошла ошибка:
{% if error!= '' %}: Это условное выражение, использующее синтаксис шаблонизатора Flask, Jinja2. Он проверяет, не пуста ли переменнаяerror. Переменнаяerrorожидается быть переданной из Flask - бэкенда в шаблон. Если есть сообщение об ошибке, условие оценивается какTrue.<p class="error_disp">{{error}}</p>: Когда условие истинно, этот элемент абзаца отображается, отображающий сообщение об ошибке, содержащееся в переменнойerror. Классerror_dispвероятно используется для стилизации сообщения об ошибке, чтобы сделать его визуально выделенным и привлечь внимание пользователя.{% endif %}: Закрывает условный блок. Если переменнаяerrorпуста, ничего из этого блока не отображается на странице.
Отображение сокращенных ссылок
Во - вторых, после успешного сокращения ссылки мы отображаем сокращенную ссылку пользователю. Это включает в себя создание раздела на главной странице, который динамически показывает сокращенную ссылку после отправки формы, вместе с кнопкой для копирования в буфер обмена для простой передачи.
Добавьте следующий код в templates/index.html:
<!-- URL Generator Display block -->
<div class="gen_block">
<p class="gen_url">
Shorty URL is
<b><a id="short-url" href="{{shorty_url}}">{{shorty_url}}</a></b>
</p>
<button
class="button-primary copy-btn"
data-clipboard-action="copy"
data-clipboard-target="#short-url"
>
Copy
</button>
</div>
{% endif %}
<!-- end block -->
Этот блок отображается, когда ссылка успешно сокращена, и предоставляет пользователям способ легко скопировать сокращенную ссылку:
{% if shorty_url %}: Еще одно условное выражение, которое проверяет, существует ли переменнаяshorty_urlи не является пустой. Эта переменная должна содержать сокращенную ссылку, сгенерированную сервисом.<p class="gen_url">: Этот абзац отображает сообщение, указывающее на сокращенную ссылку. Внутри него<a id="short-url" href="{{shorty_url}}">{{shorty_url}}</a>создает гиперссылку, где сокращенная ссылка является как текст ссылки, так и значением атрибутаhref, позволяя пользователям нажать на нее напрямую.<button>: Эта кнопка предназначена для копирования сокращенной ссылки в буфер обмена для простой передачи. Она использует классы для стилизации (button-primary) и функциональности (copy-btn). Атрибутdata-clipboard-actionзадает действие для выполнения (копирование), аdata-clipboard-targetуказывает на элемент - цель для копирования (ссылку на сокращенную ссылку). Эта настройка предполагает интеграцию Clipboard.js (или аналогичной библиотеки) для обработки функции копирования.{% endif %}: Закрывает условный блок для отображения сокращенной ссылки и кнопки копирования. Еслиshorty_urlне задан или пуста, этот раздел не будет отображаться.
Эти улучшения значительно вносят вклад в удобство использования сервиса сокращения ссылок. Сообщения об ошибках предоставляют важную обратную связь, помогая пользователям исправить ошибки или информируя их о проблемах, в то время как отображение сокращенных ссылок с функцией копирования позволяет обеспечить беспрепятственный опыт при создании и передаче сокращенных ссылок.
Перечисление и управление сокращенными URL-адресами
Последний шаг - создать раздел, в котором перечисляются все сокращенные ссылки, хранящиеся в базе данных, вместе с их исходными ссылками, количеством кликов, которые они получили, и ссылками на детальную аналитику. Эта функция позволяет пользователям просматривать и управлять своими сокращенными ссылками в одном месте, делая приложение более функциональным и удобным для пользователя.
Добавьте следующий код в templates/index.html:
<!-- URL List Block -->
{% if not error %}
{% if not shorty_url %}
<!-- Add Empty list case -> 'Wow. Such Empty!' -->
<div style="overflow-x:auto;">
<div class="table_list u-full-width">
<table>
<thead>
<tr>
<th>Original URL</th>
<th>Short URL</th>
<th>Clicks</th>
<th>Info</th>
</tr>
</thead>
<tbody>
{% for url in table %}
<tr>
<td style="padding-left: 5px;">{{url[1]}}</td>
<td><a href="{{host+url[2]}}">{{ host+url[2]}}</a></td>
<td style="text-align: center;">{{url[4]}}</td>
<td id="info"><a href=" {{url_for('analytics',short_url=url[2])}} "><i class="material-icons">info_outline</i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
{% endif %}
</div>
</div>
<script type="text/javascript">
var clipboard = new Clipboard('.copy-btn');
</script>
</html>
Этот код предназначен для перечисления всех сокращенных ссылок, хранящихся в базе данных, предоставляя информацию, такую как исходная ссылка, сокращенная ссылка, количество кликов и ссылки на более детальную аналитику. Вот подробный разбор его компонентов:
- Блок начинается с условного
{% if not error %}, чтобы убедиться, что список отображается только в отсутствие ошибок. Это помогает поддерживать чистый пользовательский интерфейс, особенно когда нужно отображать сообщения об ошибках. - Еще одно условное
{% if not shorty_url %}проверяет, не был ли только что сгенерирован новый сокращенный URL. Эта проверка может использоваться для предотвращения мгновенного отображения списка после сокращения новой ссылки, сосредоточив внимание пользователя на недавно созданной сокращенной ссылке. - Стиль
overflow-x:auto;применяется кdiv, чтобы обеспечить горизонтальную прокрутку таблицы на меньших экранах, улучшая отзывчивость и удобство использования. - Элемент
tableимеет структуру с разделомthead, определяющим заголовки столбцов для "Original URL", "Short URL", "Clicks" и "Info". Этот макет помогает пользователям понять представленные данные. - Раздел
tbodyдинамически заполняется данными с использованием цикла Flask/Jinja2:{% for url in table %}. Этот цикл перебирает коллекцию URL (table), переданную из Flask - бэкенда, отображая данные каждой ссылки в новой строке таблицы (<tr>). - В каждой строке исходная ссылка отображается в ячейке (
<td>) с некоторым отступом для эстетики. Сокращенная ссылка представлена в виде кликабельной ссылки (<a>), составленной путем добавления сокращенного пути (url[2]) к имени хоста (host), который также должен быть передан из бэкенда. - Столбец "Clicks" показывает количество раз, которое сокращенная ссылка была посещена, выровненный по центру для лучшей читаемости.
- Столбец "Info" содержит ссылку на страницу аналитики для каждой сокращенной ссылки. Эта ссылка генерируется с использованием функции
url_forFlask, динамически создавая URL для маршрута аналитики с сокращенной ссылкой в качестве параметра. Иконка (<i class="material-icons">info_outline</i>) из набора Google Material Icons используется для визуального представления ссылки на аналитику. - Тег
{% endfor %}закрывает цикл, обеспечивая создание строки для каждой ссылки в коллекцииtable. - Условные блоки закрываются тегами
{% endif %}. - Внизу тег
<script>инициализирует Clipboard.js для класса.copy-btn, который, возможно, был использован в предыдущих разделах (например, для копирования сокращенной ссылки). Этот скрипт обеспечивает, что любой элемент с классомcopy-btnбудет иметь функцию копирования в буфер обмена, используя библиотеку Clipboard.js.
Этот последний шаг завершает функциональность сервиса сокращения ссылок "Shorty", предоставляя пользователям полный обзор своих сокращенных ссылок, что делает их управление и анализ ссылками проще. Интеграция динамического рендеринга данных с Flask/Jinja2, сочетающаяся с тщательным дизайном интерфейса, обеспечивает удобный для пользователя опыт.
Создать шаблон страницы поиска
Чтобы позволить пользователям искать ссылки по тегам, нам понадобится страница поиска.
В templates/search.html добавьте следующий HTML - код:
<!DOCTYPE html>
<html>
<head>
<title>Shorty</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="stylesheet" type="text/css" href="../static/skeleton.css">
<link rel="stylesheet" type="text/css" href="../static/normalize.css">
<link rel="stylesheet" type="text/css" href="../static/main.css">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,700,900" rel="stylesheet">
</head>
<body>
<div class="container main_header">
<h3 align="left"><a href="{{url_for('index')}}">Shorty</a></h3>
<p>A dead simple URL shortener service.</p>
</div>
<!-- Search results -->
<div class=" container search_header">
<h4>Search Results for : <b> {{ search_tag }} <b></h4>
<div style="overflow-x:auto;">
<div class="table_list u-full-width">
<table>
<thead>
<tr>
<th>Original URL</th>
<th>Short URL</th>
<th>Clicks</th>
<th>Info</th>
</tr>
</thead>
<tbody>
{% for url in table %}
<tr>
<td style="padding-left: 5px;">{{url[1]}}</td>
<td><a href="{{ host+url[2]}}">{{host+url[2]}}</a></td>
<td style="text-align: center;">{{url[4]}}</td>
<td id="info"><a href=" {{url_for('analytics',short_url=url[2])}} "><i class="material-icons">info_outline</i></a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
Этот код создает шаблон для страницы результатов поиска в сервисе сокращения ссылок "Shorty". Эта страница предназначена для отображения результатов поиска пользователя по ссылкам по тегам. Вот подробный разбор шаблона:
- Внутри
<body>секция заголовка (<div class="container main_header">) отображает аналогичную секцию на главной странице, обеспечивая единый стиль и ощущение. Она включает название сервиса ("Shorty") в виде кликабельной ссылки, которая перенаправляет на главную страницу ({{url_for('index')}}), и краткое описание сервиса. - Секция
<div class="container search_header">представляет область результатов поиска, начиная с заголовка (<h4>), который динамически отображает тег, использованный для поиска ({{ search_tag }}). - Результаты отображаются в таблице внутри
div, стилизованного для горизонтальной прокрутки (overflow-x:auto;), обеспечивая доступность на устройствах с меньшими экранами. - Структура таблицы (
<table>) состоит из секций заголовка (<thead>) и тела (<tbody>). Заголовок определяет столбцы для "Original URL", "Short URL", "Clicks" и "Info", аналогично списку, отображаемому на главной странице. - Тело таблицы динамически заполняется с использованием цикла (
{% for url in table %}), перебирая коллекцию URL (table), переданную из Flask - бэкенда. Каждая итерация создает новую строку (<tr>) в таблице для каждой ссылки:- Исходная ссылка отображается с некоторым отступом для лучшей читаемости.
- Сокращенная ссылка представлена в виде кликабельной ссылки, составленной путем добавления сокращенного пути к имени хоста, оба из которых динамически вставляются с использованием синтаксиса шаблонизатора Flask.
- Столбец "Clicks" показывает, сколько раз сокращенная ссылка была посещена, с текстом выровненным по центру для ясности.
- Столбец "Info" предоставляет ссылку на подробную аналитику для каждой ссылки, используя функцию
url_forFlask для динамического генерации URL и иконку (<i class="material-icons">info_outline</i>) для визуального представления.
Этот шаблон результатов поиска улучшает сервис "Shorty", позволяя пользователям эффективно искать и управлять ссылками на основе тегов, обеспечивая беспрепятственный и интуитивный пользовательский опыт.一致ное использование стилей и элементов макета с главной страницы обеспечивает единый дизайн по всему приложению.
Создать шаблон страницы аналитики
Страница аналитики будет отображать подробную информацию о использовании сокращенной ссылки, включая количество кликов, статистику по браузерам и платформам.
В templates/data.html добавьте следующий HTML - код:
<!doctype html>
<html>
<head>
<title>Shorty</title>
<!-- Add Local SVG image when hosting. -->
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
<link rel="stylesheet" type="text/css" href="../static/skeleton.css" />
<link rel="stylesheet" type="text/css" href="../static/normalize.css" />
<link rel="stylesheet" type="text/css" href="../static/main.css" />
<link
href="https://fonts.googleapis.com/css?family=Roboto:300,400,700,900"
rel="stylesheet"
/>
</head>
<body>
<div class="container main_header">
<h3 align="left"><a href="{{url_for('index')}}">Shorty</a></h3>
<p>A dead simple URL shortener service.</p>
</div>
<div class=" container modal-content">
<!-- Array index ->
broswer :
CHROME,
FIREFOX,
SAFARI,
OTHER_BROWSER,
platform:
ANDROID,
IOS,
WINDOWS,
LINUX,
MAC,
OTHER_PLATFORM
-->
<div class="url_info">
<h4>
Analytics data for :
<a href="{{host+info[1]}}">{{'localhost/'+info[1]}}</a>
</h4>
<p>
Original URL :
<a style="text-decoration: none" href="{{info[0]}}">{{info[0]}}</a>
</p>
</div>
<div class="data_block">
<div class="browser_list">
<h4>Browser</h4>
<table>
<thead>
<tr>
<th>Chrome</th>
<th>Firefox</th>
<th>Safari</th>
<th>Other Broswers</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding-left: 5px;">{{browser[0]}}</td>
<td>{{browser[1]}}</td>
<td>{{browser[2]}}</td>
<td>{{browser[3]}}</td>
</tr>
</tbody>
</table>
</div>
<div class="platform_list">
<h4>Platform</h4>
<table>
<thead>
<tr>
<th>Android</th>
<th>IOS</th>
<th>Windows</th>
<th>Linux</th>
<th>Mac</th>
<th>Other Platforms</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding-left: 5px;">{{platform[0]}}</td>
<td>{{platform[1]}}</td>
<td>{{platform[2]}}</td>
<td>{{platform[3]}}</td>
<td>{{platform[4]}}</td>
<td>{{platform[5]}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
Этот код включает информацию о количестве кликов, использовании браузеров и распределении по платформам. Вот разбор его структуры и компонентов:
divс классамиcontainer modal-contentзаключает аналитическую информацию, стилизованную как модальное окно или отдельный блок контента на странице.divurl_infoпредставляет:- Заголовок
<h4>, указывающий, что следующие данные относятся к аналитике для определенной сокращенной ссылки. Сокращенная ссылка отображается в виде кликабельной ссылки, составленной с использованием переменныхhostиinfo[1], гдеinfo[1]содержит сокращенный путь. - Абзац (
<p>), показывающий исходную ссылку в виде кликабельной ссылки, обеспечивая доступ к исходному контенту.
- Заголовок
- Два отдельных раздела,
browser_listиplatform_list, каждый содержит таблицу, отображающую статистику использования для браузеров и платформ соответственно:- Раздел
browser_listвключает таблицу с заголовками для Chrome, Firefox, Safari и Другие браузеры. Раздел<tbody>отображает соответствующие статистики, которые извлекаются из массива переменнойbrowser, переданного в шаблон. - Аналогично, раздел
platform_listимеет таблицу для использования платформ, с заголовками для Android, iOS, Windows, Linux, Mac и Другие платформы. Статистика использования показывается в теле таблицы, взятая из массива переменнойplatform.
- Раздел
- Таблицы используют
<thead>для заголовков и<tbody>для фактических данных, обеспечивая семантический HTML и облегчая стилизацию и доступность. - Ячейки данных (
<td>) внутри таблиц отображают соответствующие количества для каждого браузера и платформы, выровнены и стилизованы для лучшей читаемости.
Этот шаблон эффективно передает аналитические данные пользователю, предоставляя информацию о том, как сокращенная ссылка используется, включая браузеры и платформы, используемые аудиторией. Чистый макет, сочетающийся с четким разделением данных на отдельные секции, делает it easy для пользователей понять и интерпретировать производительность их ссылки.
Создать шаблон страницы 404
Настраиваемая страница 404 улучшает пользовательский опыт, предоставляя более полезное сообщение об ошибке, когда сокращенная ссылка не найдена.
В templates/404.html добавьте следующий HTML - код:
<!doctype html>
<html>
<head>
<title>Shorty</title>
<!-- Add Local SVG image when hosting. -->
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet"
/>
<link rel="stylesheet" type="text/css" href="../static/skeleton.css" />
<link rel="stylesheet" type="text/css" href="../static/normalize.css" />
<link rel="stylesheet" type="text/css" href="../static/main.css" />
<link
href="https://fonts.googleapis.com/css?family=Roboto:300,400,700,900"
rel="stylesheet"
/>
</head>
<body>
<div class="lost">
<h2>Oi, chap you seem lost!</h2>
</div>
</body>
</html>
Этот настраиваемый шаблон страницы 404 эффективно сообщает пользователям, что страница, которую они ищут, не существует, при этом поддерживая легкомысленный тон.
Проектировать веб-интерфейс
Далее мы создадим веб - интерфейс. Начнем с создания основного файла CSS для стилизации нашего приложения.
В static/main.css добавьте следующий CSS - код для стилизации HTML - элементов:
html {
border-top: 5px solid #d9edf7;
}
body {
font-family: "Roboto", sans-serif;
margin-top: 50px;
margin-bottom: 0;
}
h3 {
padding: 0;
margin: 0;
}
h3 a {
font-weight: 700;
text-decoration: none;
color: black;
}
h3 a:hover {
color: grey;
transition: 0.2s all;
}
/** Main Header */
.main_header {
margin-bottom: 20px;
}
/* Search Block */
.search_url_block {
padding: 15px;
background-color: #d9edf7;
color: #31708f;
border-radius: 5px;
margin-bottom: 10px;
}
form {
margin: 0;
}
.search_header {
margin-top: 20px;
}
.material-icons {
padding: 5px;
padding-top: 7px;
opacity: 0.7;
}
.material-icons:hover {
opacity: 1;
}
/* Gen URL block */
.gen_block {
margin-top: 10px;
padding: 15px;
background-color: #dff0d8;
color: #2b542c;
border-radius: 5px;
width: auto;
font-size: 20px;
}
/* Error Disp */
.error_disp {
padding: 15px;
border-radius: 5px;
background-color: #fcf8e3;
color: #b84442;
width: auto;
font-size: 20px;
margin-top: 10px;
}
/* Table Display Block*/
.table_list {
padding-top: 10px;
margin-top: 40px;
border-top: 2px solid lightgrey;
}
table {
font-size: 20px;
width: 100%;
}
thead {
font-weight: 700;
padding: 2px;
}
tbody {
font-weight: 400;
}
th {
padding: 5px;
}
td {
padding: 5px;
}
tr {
padding: 5px;
}
tbody tr:hover {
background-color: #f5f5f5;
transition: 0.1s all ease-out;
}
/* Analytics block*/
.url_info {
margin-top: 10px;
padding: 15px;
background-color: #d9edf7;
color: #31708f;
border-radius: 5px;
margin-bottom: 10px;
}
.url_info h4,
p {
margin: 0;
padding: 0;
}
.data_block {
margin-top: 20px;
}
/* 404. Lost*/
.lost {
margin-top: 20px;
}
.lost h2 {
font-weight: 700;
font-size: 40px;
text-align: center;
color: #31708f;
}
.lost p {
font-weight: 400;
font-size: 20px;
text-align: center;
}
В целом дизайн использует комбинацию цветов фона, цветов текста и отступов для создания чистого, современного интерфейса, который легко использовать. Использование скругления углов у различных элементов дает интерфейсу более мягкий, доступный вид, в то время как эффекты наведения мыши повышают интерактивность. Consistentное использование шрифта Roboto обеспечивает единый стиль по всему приложению.
Функции подключения и работы с базой данных
Утилита-функции будет обрабатывать подключения к базе данных, проверять валидность URL-адресов, обновлять счетчики браузеров и платформ, а также генерировать случайные токены для сокращенных URL-адресов.
Подключение к базе данных
Сначала вы настроите подключение к базе данных с использованием pymysql. Это至关重要 для взаимодействия вашего Flask-приложения с базой данных MySQL.
В utils.py добавьте следующий Python-код:
from urllib.parse import urlparse
import random
import string
import pymysql
db_config = {
"host": "localhost",
"user": "root",
"password": "",
"db": "SHORTY"
}
def get_db_connection() -> pymysql.Connection:
"""Создает и возвращает новое подключение к базе данных."""
return pymysql.connect(**db_config)
- Библиотека
pymysqlиспользуется для подключения к базе данных MySQL. Эта библиотека позволяет Python-приложениям взаимодействовать с базами данных MySQL с использованием простого API. - Словарь
db_configсодержит параметры подключения к базе данных, такие как хост, пользователь, пароль и имя базы данных. Эти параметры импортируются из отдельного модуляconfig,大概是出于更好的安全性和模块化考虑。Разделение настроек позволяет更容易进行调整,而无需修改主要的代码库。 - Функция
get_db_connection()создает и возвращает новое подключение к базе данных с использованием функцииpymysql.connect(**db_config). Синтаксис**db_configиспользуется для распаковки словаря в именованные аргументы.
Функции операций с базой данных
После установления подключения к базе данных следующим шагом является создание функций, которые выполняют операции с базой данных. Это включает перечисление данных для заданного сокращенного URL-адреса и обновление счетчиков на основе использования браузера и платформы.
В utils.py добавьте следующий Python-код:
def list_data(shorty_url: str) -> tuple:
"""
Принимает short_url в качестве входных данных.
Возвращает счетчик, браузер, количество обращений по платформам.
"""
with get_db_connection() as conn, conn.cursor() as cursor:
su = [shorty_url]
info_sql = "SELECT URL, S_URL, TAG FROM WEB_URL WHERE S_URL = %s; "
counter_sql = "SELECT COUNTER FROM WEB_URL WHERE S_URL = %s; "
browser_sql = "SELECT CHROME, FIREFOX, SAFARI, OTHER_BROWSER FROM WEB_URL WHERE S_URL = %s;"
platform_sql = "SELECT ANDROID, IOS, WINDOWS, LINUX, MAC, OTHER_PLATFORM FROM WEB_URL WHERE S_URL = %s;"
cursor.execute(info_sql, su)
info_fetch = cursor.fetchone()
cursor.execute(counter_sql, su)
counter_fetch = cursor.fetchone()
cursor.execute(browser_sql, su)
browser_fetch = cursor.fetchone()
cursor.execute(platform_sql, su)
platform_fetch = cursor.fetchone()
return info_fetch, counter_fetch, browser_fetch, platform_fetch
def update_counters(cursor: pymysql.Connection, short_url: str, browser_dict: dict, platform_dict: dict) -> None:
"""Обновляет счетчики браузера и платформы в базе данных для заданного short_url."""
counter_sql = """UPDATE WEB_URL SET COUNTER = COUNTER + 1,
CHROME = CHROME + %s, FIREFOX = FIREFOX + %s, SAFARI = SAFARI + %s, OTHER_BROWSER = OTHER_BROWSER + %s,
ANDROID = ANDROID + %s, IOS = IOS + %s, WINDOWS = WINDOWS + %s, LINUX = LINUX + %s, MAC = MAC + %s, OTHER_PLATFORM = OTHER_PLATFORM + %s
WHERE S_URL = %s;"""
cursor.execute(counter_sql, (browser_dict['chrome'], browser_dict['firefox'], browser_dict['safari'], browser_dict['other'],
platform_dict['android'], platform_dict['iphone'], platform_dict[
'windows'], platform_dict['linux'], platform_dict['macos'], platform_dict['other'],
short_url))
- Функция
list_data(shorty_url)предназначена для извлечения различных частей информации из таблицыWEB_URLдля заданного сокращенного URL-адреса (shorty_url). Она устанавливает соединение с базой данных и выполняет четыре SQL-запроса для извлечения исходного URL-адреса, связанного тега, счетчика доступов, информации о браузере и платформе. Каждый запрос выполняется отдельно, и результаты извлекаются и возвращаются. - Функция
update_counters(cursor, short_url, browser_dict, platform_dict)обновляет счетчик доступов, информацию о браузере и платформе для заданного сокращенного URL-адреса в базе данных. Эта функция принимает курсор базы данных, сокращенный URL-адрес и два словаря, содержащих подсчеты для каждого браузера и платформы, в качестве аргументов. Она строит SQL-запросUPDATE, чтобы увеличить счетчики для сокращенного URL-адреса на основе предоставленных данных. Функция предполагает, что информация о браузере и платформе была определена перед вызовом этой функции, и что эта информация передается в виде словарей (browser_dictиplatform_dict), с ключами, соответствующими столбцам в таблицеWEB_URL.
Это стандартная схема для веб-приложений, использующих Flask и MySQL, где определяются утилита-функции для общих операций с базой данных. Затем эти функции могут быть импортированы и использованы в приложении для взаимодействия с базой данных, выделяя непосредственный доступ к базе данных и SQL-запросы от основной логики приложения.
Реализовать вспомогательные функции, не связанные с базой данных
Наконец, реализуйте утилитарные функции, которые не взаимодействуют с базой данных. Это включает в себя генерацию случайных токенов для сокращенных URL-адресов и проверку валидности URL-адресов.
В utils.py добавьте следующий Python-код:
def random_token(size: int = 6) -> str:
"""
Генерирует случайную строку длиной 6 символов, используя аргумент size
для изменения размера токена.
Возвращает валидный токен заданного размера,
*по умолчанию размер 6 символов
"""
BASE_LIST = string.digits + string.ascii_letters
token = ''.join((random.choice(BASE_LIST)) for char in range(size))
return token
def url_check(url: str) -> bool:
"""
Ожидает строку в качестве аргумента.
Возвращает True, если URL-адрес валиден, иначе False.
Для более подробной документации ознакомьтесь с urlparse.
"""
try:
result = urlparse(url)
if all([result.scheme, result.netloc]):
return True
else:
return False
except:
return False
- Функция
random_tokenгенерирует случайную строку, которая служит токеном для создания сокращенных URL-адресов. По умолчанию она создает токен длиной 6 символов, но его размер можно изменить с помощью аргументаsize.- Она использует комбинацию цифр (
string.digits) и букв (string.ascii_letters) в качестве базового списка для генерации токена. - Токен генерируется путем случайного выбора символов из
BASE_LISTв количестве, указанном параметромsize. Это делается с использованием списочного выражения иrandom.choice(), который выбирает случайный элемент из указанной последовательности. - Затем сгенерированный токен возвращается в виде строки. Этот токен может быть использован в качестве идентификатора сокращенного URL-адреса.
- Она использует комбинацию цифр (
- Функция
url_checkпроверяет валидность заданного URL-адреса, чтобы убедиться, что он имеет правильный формат.- Она использует функцию
urlparseиз модуляurllib.parseдля разбора заданного URL-адреса на компоненты. - Функция проверяет, содержит ли URL-адрес как схему (например,
http,https), так и сетевой адрес (netloc, например,www.example.com). Оба эти компонента являются обязательными для того, чтобы URL-адрес считался валидным. - Если оба компонента присутствуют, функция возвращает
True, что означает, что URL-адрес валиден. Если какой-либо из них отсутствует, или если во время разбора возникает исключение (например, если входные данные не являются строкой), функция возвращаетFalse. - Эта проверка важна для обеспечения того, чтобы только валидные URL-адреса обрабатывались и хранились приложением.
- Она использует функцию
Эти утилитарные функции являются неотъемлемой частью сервиса сокращения URL-адресов, обеспечивая важные возможности для генерации уникальных идентификаторов для сокращенных URL-адресов и гарантии того, что только валидные URL-адреса принимаются системой.
Инициализация и реализация маршрута index
Наконец, мы построим ядро нашего сервиса сокращения URL-адресов - приложение Flask.
Начните с настройки маршрута главной страницы. Этот маршрут будет обслуживать главную страницу и обрабатывать как GET-, так и POST-запросы. При GET-запросе он отображает все сокращенные URL-адреса. При POST-запросе он принимает новый URL-адрес для сокращения, генерирует уникальный токен и сохраняет его в базу данных.
В app.py добавьте следующий Python-код:
from flask import Flask, request, redirect, render_template, make_response
from utils import get_db_connection, list_data, random_token, update_counters, url_check
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
with get_db_connection() as conn, conn.cursor() as cursor:
## Получить все данные для отображения на главной странице
cursor.execute("SELECT * FROM WEB_URL;")
result_all_fetch = cursor.fetchall()
if request.method == 'POST':
og_url = request.form.get('url_input')
custom_suff = request.form.get('url_custom', '')
tag_url = request.form.get('url_tag', '')
token_string = random_token() if not custom_suff else custom_suff
if og_url and url_check(og_url):
cursor.execute(
"SELECT S_URL FROM WEB_URL WHERE S_URL = %s FOR UPDATE", (token_string,))
if cursor.fetchone() is None:
cursor.execute(
"INSERT INTO WEB_URL(URL, S_URL, TAG) VALUES(%s, %s, %s)", (og_url, token_string, tag_url))
conn.commit()
return render_template('index.html', shorty_url=f"{shorty_host}{token_string}")
else:
error = "The custom suffix already exists. Please use another suffix or leave it blank for a random one."
else:
error = "Invalid URL provided. Please enter a valid URL."
return render_template('index.html', table=result_all_fetch, host=shorty_host, error=error)
return render_template('index.html', table=result_all_fetch, host=shorty_host)
Функция index в app.py настраивает основную функциональность сервиса сокращения URL-адресов с использованием Flask, микрофреймворка для веб-приложений, написанного на Python. Эта функция определяет, как маршрут главной страницы (/) приложения ведет себя и обрабатывает как GET-, так и POST-запросы. Вот подробное объяснение кода:
Настройка Flask
- Приложение Flask инициализируется с помощью
app = Flask(__name__). - Декоратор
@app.route('/', methods=['GET', 'POST'])указывает, что функцияindexобрабатывает запросы к корневому URL (/) и принимает как GET-, так и POST-методы.
Обработка GET-запросов
- Когда функция получает GET-запрос, она подключается к базе данных с использованием утилитарной функции
get_db_connection()и извлекает все записи из таблицыWEB_URL. Это для отображения всех сокращенных URL-адресов на главной странице. - Извлеченные записи передаются в функцию
render_template, вместе с URL-адресом хоста (shorty_host), для отображения шаблонаindex.html. Этот шаблон, вероятно, содержит таблицу или список для отображения каждого сокращенного URL-адреса и его деталей.
Обработка POST-запросов
- Для POST-запросов, обычно отправляемых из формы на главной странице, функция извлекает исходный URL (
og_url), необязательный пользовательский суффикс (custom_suff) и необязательный тег (tag_url) из данных формы. - Затем она генерирует случайный токен для сокращенного URL-адреса с использованием
random_token(), если не предоставлен пользовательский суффикс. Этот токен (или пользовательский суффикс) служит уникальным идентификатором для сокращенного URL-адреса. - Перед выполнением функция проверяет валидность исходного URL-адреса с использованием
url_check(og_url). Если URL-адрес валиден и токен/суффикс уникален (не существует в базе данных), новая запись вставляется в таблицуWEB_URLс исходным URL-адресом, токеном/суффиксом в качестве сокращенного URL-адреса и тегом. - Если операция прошла успешно, функция переотображает шаблон
index.html, отображая новый сокращенный URL-адрес (shorty_url), вместе с всеми существующими записями. - Если токен/суффикс уже существует в базе данных или исходный URL-адрес невалиден, устанавливается сообщение об ошибке, и шаблон
index.htmlотображается с сообщением об ошибке и существующими записями.
Обработка ошибок и рендеринг шаблонов
- Функция
render_templateшироко используется для отображения шаблонаindex.html, передав в него различные параметры, такие как список всех записей (table), базовый URL-адрес хоста для сокращенных ссылок (host), новый сокращенный URL-адрес (shorty_url) и любые сообщения об ошибке (error). Эта функция облегчает динамическое отображение содержимого в Flask путем вставки переменных Python в HTML-шаблоны.
Это приложение Flask служит в качестве бэкенда для сервиса сокращения URL-адресов, обрабатывая взаимодействие с базой данных, проверку валидности URL-адресов и генерацию токенов, а также динамически генерируя веб-страницы на основе взаимодействия пользователя и содержимого базы данных.
Реализовать маршрут перенаправления и маршрут аналитики
Маршрут перенаправления
Далее, создайте маршрут для обработки перенаправления от сокращенного URL-адреса к исходному URL-адресу. Этот маршрут ловит любой сокращенный URL-адрес, ищет его в базе данных и перенаправляет пользователя на исходный URL-адрес.
Добавьте следующий код в app.py:
@app.route('/<short_url>')
def reroute(short_url):
with get_db_connection() as conn, conn.cursor() as cursor:
platform = request.user_agent.platform or 'other'
browser = request.user_agent.browser or 'other'
browser_dict = {'firefox': 0, 'chrome': 0,'safari': 0, 'other': 0}
platform_dict = {'windows': 0, 'iphone': 0,
'android': 0, 'linux': 0,'macos': 0, 'other': 0}
## Увеличить счетчики браузера и платформы
browser_dict[browser] = browser_dict.get(browser, 0) + 1
platform_dict[platform] = platform_dict.get(platform, 0) + 1
cursor.execute(
"SELECT URL FROM WEB_URL WHERE S_URL = %s;", (short_url,))
try:
new_url = cursor.fetchone()[0]
update_counters(cursor, short_url, browser_dict, platform_dict)
conn.commit()
return redirect(new_url)
except Exception:
return render_template('404.html'), 404
- Декоратор
@app.route('/<short_url>')создает динамический маршрут, который соответствует любому сегменту пути, следующему за корневым URL-адресом. Этот сегмент (short_url) передается в функциюrerouteв качестве аргумента. - Внутри функции она устанавливает соединение с базой данных и инициализирует словари для отслеживания браузера и платформы, из которой пришел запрос. Используется
request.user_agentFlask для определения браузера и платформы. - Затем она выполняет SQL-запрос, чтобы найти исходный URL-адрес, связанный с заданным
short_url. Если найден, она обновляет счетчики для браузера и платформы в базе данных с использованием функцииupdate_counters. - После внесения изменений в базу данных функция использует функцию
redirectFlask для отправки пользователя на исходный URL-адрес. - Если
short_urlне найден в базе данных или возникает любое другое исключение, функция отображает страницу ошибки 404 с использованиемrender_template('404.html').
Маршрут аналитики
Создайте маршрут аналитики, который отображает подробную информацию о конкретном сокращенном URL-адресе, таких как количество раз, которое он был посещен, и с каких платформ и браузеров.
Добавьте следующий код в app.py:
@app.route('/analytics/<short_url>')
def analytics(short_url):
info_fetch, counter_fetch, browser_fetch, platform_fetch = list_data(
short_url)
return render_template("data.html", host=shorty_host, info=info_fetch, counter=counter_fetch, browser=browser_fetch, platform=platform_fetch)
- Декоратор
@app.route('/analytics/<short_url>')определяет маршрут для доступа к аналитике о конкретном сокращенном URL-адресе.short_urlизвлекается из пути URL-адреса и передается в функциюanalytics. - Функция вызывает
list_data(short_url), которая запрашивает базу данных для получения информации о сокращенном URL-адресе, включая количество раз, которое он был посещен, и распределение доступов по разным браузерам и платформам. - Затем полученные данные (
info_fetch,counter_fetch,browser_fetch,platform_fetch) передаются в функциюrender_templateвместе с URL-адресом хоста (shorty_host) для отображения шаблонаdata.html. Этот шаблон, вероятно, представляет аналитические данные в удобочитаемом формате, таких как таблицы или диаграммы.
Эти маршруты расширяют функциональность сервиса сокращения URL-адресов, позволяя не только перенаправлять пользователей из сокращенных URL-адресов на их исходные назначения, но и предоставлять информацию о том, как эти сокращенные URL-адреса используются, включая количество доступов и типы устройств и браузеров, с которых ссылки открываются. Эта информация может быть ценной для понимания охвата и влияния общих URL-адресов.
Реализовать маршрут поиска и запустить приложение
Маршрут поиска
Настройте маршрут поиска, чтобы пользователи могли искать сокращенные URL-адреса по тегам. Этот маршрут обрабатывает как GET-, так и POST-запросы, отображает форму поиска и обрабатывает запросы поиска соответственно.
Добавьте следующий код в app.py:
@app.route('/search', methods=['GET', 'POST'])
def search():
s_tag = request.form.get('search_url', '')
if not s_tag:
return render_template('index.html', error="Please enter a search term.")
with get_db_connection() as conn, conn.cursor() as cursor:
cursor.execute("SELECT * FROM WEB_URL WHERE TAG = %s", (s_tag,))
search_tag_fetch = cursor.fetchall()
return render_template('search.html', host=shorty_host, search_tag=s_tag, table=search_tag_fetch)
- Декоратор
@app.route('/search', methods=['GET', 'POST'])настраивает маршрут по адресу/search, обрабатывая как GET-, так и POST-запросы. Хотя GET-запрос может быть использован для отображения формы поиска, POST-запрос обрабатывает данные формы, отправленные пользователями. - Внутри функции
searchrequest.form.get('search_url', '')пытается извлечь термин поиска из отправленных данных формы. Второй параметр ('') является значением по умолчанию, если'search_url'не найден, тем самым делающий термин поиска пустой строкой в таких случаях. - Если не предоставлен термин поиска (
not s_tag), функция перенаправляет пользователя на главную страницу с сообщением об ошибке, указывающим на необходимость ввода термина поиска. - Если термин поиска предоставлен, функция подключается к базе данных и выполняет SQL-запрос, чтобы найти все записи в таблице
WEB_URL, где столбецTAGсоответствует предоставленному термину поиска. Это позволяет пользователям найти все сокращенные URL-адреса, связанные с определенным тегом. - Результаты этого запроса (
search_tag_fetch) затем передаются в функциюrender_template, вместе с URL-адресом хоста (shorty_host) и термином поиска (s_tag), для отображения шаблонаsearch.html. Этот шаблон, вероятно, отображает результаты в виде списка или таблицы, позволяя пользователям увидеть все соответствующие записи и, возможно, взаимодействовать с ними (например, посетить исходные URL-адреса, просмотреть аналитику).
Запуск приложения
Наконец, добавьте код для запуска вашего приложения Flask. Это включает настройку хоста и порта, на котором приложение будет слушать, а также указание переменных окружения.
Добавьте следующий код в конец app.py:
shorty_host = "https://****.labex.io/"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Примечание: Вы должны заменить URL в shorty_host на URL текущей среды. Вы можете найти его, перейдя в вкладку Web 8080, и URL должен заканчиваться на /.

Теперь вы можете запустить проект с помощью следующей команды:
python app.py
Перейдите в вкладку "Web 8080" и обновите веб-страницу, чтобы увидеть следующие эффекты.
Преобразуйте URL с/без пользовательского суффикса, Поиск URL-адресов по тегу, Перейдите по ссылке:
Просмотрите информацию об операционной системе и платформе, использованной для доступа к ссылке:
Резюме
Поздравляем с завершением проекта по сокращению URL-адресов! Эта утилита упрощает обмен длинными URL-адресами, создавая более короткие и удобные для управления ссылки. Однако, необходимо иметь в виду несколько важных аспектов:
Длина базового URL-адреса: Если базовый URL-адрес самого сервиса сокращения длинный, результирующие сокращенные URL-адреса могут быть не такими короткими, как ожидается (как в проекте). Общая длина сокращенного URL-адреса включает в себя базовый URL-адрес, что может ограничить эффективность сервиса сокращения. Чтобы получить наиболее компактные URL-адреса, рассмотрите использование более короткого базового URL-адреса или доменного имени для вашего сервиса.
Ограничения внедрения на веб-сайте: Вы можете столкнуться с ошибками, такими как "Refused to display 'https://scholar.google.com/' in a frame because it set 'X-Frame-Options' to'sameorigin'." Эта ошибка возникает потому, что некоторые веб-сайты используют HTTP-заголовок
X-Frame-Options, чтобы предотвратить отображение их содержимого в iframe на других доменах, повышая безопасность против атак "clickjacking". Когда сайт устанавливает этот заголовок вsameorigin, он ограничивает внедрение до iframe, которые имеют одинаковый источник. Это не ограничение сервиса сокращения URL-адресов, а мера безопасности, реализованная целевым веб-сайтом. Для бесперебойного перенаправления лучше использовать сокращенные URL-адреса в качестве прямых ссылок, а не внедрять их в iframe.
Эти аспекты подчеркивают баланс между удобством и безопасностью в веб-разработке и важность осведомленности пользователей для оптимального использования инструментов.



