• Добро пожаловать на сайт - wlux.net!

    FAQ по форуму

    1. Все сообщения до группы местный проходят модерацию от 1 минуты до 24 часа

    2. Сообщения учитываются в следующих разделах: Читать

    3.Что-бы скачать вложение нужно 2 сообщения.

    4.Личные переписки не работают на форуме

    5. Запрещено: Просить скрытый текст , спам, реклама, скам, ддос, кардинг и другая чернуха, нарушать любые законы РФ/СНГ = бан аккаунта

    6. Внимание! Мы не удаляем аккаунты с форума! Будьте внимательны ДО регистрации! Как удалить аккаунт на форуме?!

    5.Не понимаю, как и что тут работает у вас?!Как создавать темы, писать сообщения, как получать реакции. Почему не засчитывает сообщения. Все ответы здесь

This is a mobile optimized page that loads fast, if you want to load the real page, click this text.

Софт Софт для копирования сайтов

Оффлайн

forwebhr

Местный
Участник
LV
3
 
07.06.2024
44
2
36
Награды
6
29

Репутация:

  • Автор темы
  • #1
Самописный софт для копирования сайтов. Нужен далеко не всем, так как существует

Пожалуйста, войдите или зерегистрируйтесь, чтобы увидеть скрытый текст.

, но в нем есть ограничения, когда пытаешься стырить лендинги, которые через клоаку работают (не можешь просматривать что именно по ссылке ты копируешь и после нескольких копий клоака начнет тебя закидывать на один и тот же лендинг).
Мой софт имитирует браузер на хромиуме и клоаки работают с ним, как с простым пользователем. Можно просматривать лендинги, и если лендинг нужен\нравится - жмем "Копировать" и выбираем куда сохранить.

Если кто с MacOS -

Пожалуйста, войдите или зерегистрируйтесь, чтобы увидеть скрытый текст.

(для ленивых, кто с консолью не работает).

Или сам код - сохранить в файл .py и запустить через консоль (потребует установить 3 модуля, просто вводим pip install ТО что консоль попросила).

Браузер для копирования сайтов:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QWidget, QMessageBox, QFileDialog
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
import requests
from bs4 import BeautifulSoup
import os
import zipfile
from urllib.parse import urljoin, urlparse

class CustomWebEnginePage(QWebEnginePage):
    def certificateError(self, certificate):
        return True

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Браузер")
        self.setGeometry(100, 100, 800, 600)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.main_layout = QVBoxLayout(self.central_widget)

        # Панель навигации (Назад, Вперед, Адресная строка)
        navigation_layout = QHBoxLayout()

        self.back_button = QPushButton("←")
        navigation_layout.addWidget(self.back_button)

        self.forward_button = QPushButton("→")
        navigation_layout.addWidget(self.forward_button)

        self.url_bar = QLineEdit()
        navigation_layout.addWidget(self.url_bar)
        self.url_bar.returnPressed.connect(self.load_url)

        self.go_button = QPushButton("Перейти")
        navigation_layout.addWidget(self.go_button)

        self.main_layout.addLayout(navigation_layout)

        self.browser = QWebEngineView()
        self.browser.setPage(CustomWebEnginePage())
        self.main_layout.addWidget(self.browser)
        self.browser.urlChanged.connect(self.update_url_bar)

        # Подключаем сигналы к кнопкам навигации после создания browser
        self.back_button.clicked.connect(self.browser.back)
        self.forward_button.clicked.connect(self.browser.forward)

        # Кнопка "Копировать сайт"
        self.copy_button = QPushButton("Копировать сайт")
        self.copy_button.clicked.connect(self.copy_website)
        self.main_layout.addWidget(self.copy_button)

        self.current_url = ""

    def update_url_bar(self, url):
        self.url_bar.setText(url.toString())
        self.current_url = url.toString()

    def load_url(self):
        url = self.url_bar.text()
        if url:
            self.current_url = url
            self.browser.load(QUrl(url))
        else:
            QMessageBox.warning(self, "Предупреждение", "Пожалуйста, введите URL.")

    def browser_back(self):
        self.browser.back()

    def browser_forward(self):
        self.browser.forward()

    def copy_website(self):
        if not self.current_url:
            QMessageBox.warning(self, "Предупреждение", "Пожалуйста, сначала перейдите на сайт.")
            return

        options = QFileDialog.Options()
        download_dir = QFileDialog.getExistingDirectory(self, "Выберите папку для сохранения", "", options=options)
        if not download_dir:
            return

        parsed_url = urlparse(self.current_url)
        base_name = parsed_url.netloc
        if not base_name:
            base_name = "copied_website"
        zip_filename = os.path.join(download_dir, f"{base_name}.zip")

        QMessageBox.information(self, "Копирование", f"Начинается копирование сайта: {self.current_url} в архив: {zip_filename}")

        page = self.browser.page()
        try:
            page.toHtml(lambda html: self.process_html(html, self.current_url, zip_filename))
        except Exception as e:
            QMessageBox.showerror(self, "Ошибка при получении HTML", str(e))
            print(f"Произошла ошибка при получении HTML: {e}")

    def process_html(self, html_content, base_url, zip_filename):
        soup = BeautifulSoup(html_content, 'html.parser')
        resources = []
        parsed_base_url = urlparse(base_url)
        base_netloc = parsed_base_url.netloc

        for tag in soup.find_all(['link', 'script', 'img', 'source']):
            if tag.name == 'link' and tag.has_attr('href'):
                resources.append(tag['href'])
            elif tag.name == 'script' and tag.has_attr('src'):
                resources.append(tag['src'])
            elif tag.name == 'img' and tag.has_attr('src'):
                resources.append(tag['src'])
            elif tag.name == 'source' and tag.has_attr('srcset'):
                for src in tag['srcset'].split(','):
                    resources.append(src.strip().split()[0])

        downloaded_paths = {}
        with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zf:
            zf.writestr(os.path.join(base_netloc, 'index.html'), html_content.encode('utf-8'))

            for resource_url in resources:
                absolute_url = urljoin(base_url, resource_url)
                parsed_resource_url = urlparse(absolute_url)
                if parsed_resource_url.netloc == base_netloc or not parsed_resource_url.netloc:
                    resource_path = parsed_resource_url.path.lstrip('/')
                    archive_path = os.path.join(base_netloc, resource_path)
                    try:
                        response = requests.get(absolute_url, stream=True)
                        response.raise_for_status()
                        zf.writestr(archive_path, response.content)
                        downloaded_paths[resource_url] = archive_path
                        print(f"Сохранен ресурс: {absolute_url} -> {archive_path}")
                    except requests.exceptions.RequestException as e:
                        print(f"Ошибка при скачивании {absolute_url}: {e}")

            updated_html = html_content
            for original_url, new_path in downloaded_paths.items():
                updated_html = self.update_html_links(updated_html, original_url, new_path)

            zf.writestr(os.path.join(base_netloc, 'index.html'), updated_html.encode('utf-8'))

        QMessageBox.information(self, "Копирование", f"Копирование завершено. Сайт сохранен в: {zip_filename}")

    def update_html_links(self, html_content, original_url, new_path):
        soup = BeautifulSoup(html_content, 'html.parser')
        parsed_base_url = urlparse(self.current_url)
        base_netloc = parsed_base_url.netloc
        html_folder_path = os.path.join(base_netloc)

        for tag in soup.find_all(['link', 'script', 'img', 'source']):
            if tag.name == 'link' and tag.has_attr('href'):
                original_href = tag['href']
                absolute_original_href = urljoin(self.current_url, original_href)
                absolute_downloaded_url = urljoin(self.current_url, original_url)
                if absolute_original_href == absolute_downloaded_url:
                    if original_href.startswith('/'):
                        tag['href'] = os.path.join(base_netloc, original_href[1:]).replace('\\', '/') # Удалили ведущий слеш
                    else:
                        tag['href'] = os.path.relpath(new_path, html_folder_path).replace('\\', '/')
                    print(f"Обновлена CSS ссылка: {original_href} -> {tag['href']}")
            elif tag.name == 'script' and tag.has_attr('src'):
                original_src = tag['src']
                absolute_original_src = urljoin(self.current_url, original_src)
                absolute_downloaded_url = urljoin(self.current_url, original_url)
                if absolute_original_src == absolute_downloaded_url:
                    if original_src.startswith('/'):
                        tag['src'] = os.path.join(base_netloc, original_src[1:]).replace('\\', '/') # Удалили ведущий слеш
                    else:
                        tag['src'] = os.path.relpath(new_path, html_folder_path).replace('\\', '/')
            elif tag.name == 'img' and tag.has_attr('src'):
                original_src = tag['src']
                absolute_original_src = urljoin(self.current_url, original_src)
                absolute_downloaded_url = urljoin(self.current_url, original_url)
                if absolute_original_src == absolute_downloaded_url:
                    if original_src.startswith('/'):
                        tag['src'] = os.path.join(base_netloc, original_src[1:]).replace('\\', '/') # Удалили ведущий слеш
                    else:
                        tag['src'] = os.path.relpath(new_path, html_folder_path).replace('\\', '/')
            elif tag.name == 'source' and tag.has_attr('srcset'):
                srcset_values = []
                for src in tag['srcset'].split(','):
                    s = src.strip().split()
                    url = s[0]
                    absolute_original_srcset_url = urljoin(self.current_url, url)
                    absolute_downloaded_url = urljoin(self.current_url, original_url)
                    if absolute_original_srcset_url == absolute_downloaded_url:
                        if url.startswith('/'):
                            srcset_values.append(os.path.join(base_netloc, url[1:]).replace('\\', '/') + (f' {s[1]}' if len(s) > 1 else '')) # Удалили ведущий слеш
                        else:
                            srcset_values.append(os.path.relpath(new_path, html_folder_path).replace('\\', '/') + (f' {s[1]}' if len(s) > 1 else ''))
                    else:
                        srcset_values.append(src)
                tag['srcset'] = ', '.join(srcset_values)
        return html_content

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())
 

Поиск по форуму

Похожие темы:

Ответы
28
Просмотры
2 тыс.
Ответы
11
Просмотры
1 тыс.
Данный сайт использует cookie. Вы должны принять их для продолжения использования. Узнать больше....