🚀 Full project sync: Hotels RAG & Audit System
✨ Major Features: - Complete RAG system for hotel website analysis - Hybrid audit with BGE-M3 embeddings + Natasha NER - Universal horizontal Excel reports with dashboards - Multi-region processing (SPb, Orel, Chukotka, Kamchatka) 📊 Completed Regions: - Орловская область: 100% (36/36) - Чукотский АО: 100% (4/4) - г. Санкт-Петербург: 93% (893/960) - Камчатский край: 87% (89/102) 🔧 Infrastructure: - PostgreSQL with pgvector extension - BGE-M3 embeddings API - Browserless for web scraping - N8N workflows for automation - S3/Nextcloud file storage 📝 Documentation: - Complete DB schemas - API documentation - Setup guides - Status reports
This commit is contained in:
361
advanced_stealth_parser.py
Normal file
361
advanced_stealth_parser.py
Normal file
@@ -0,0 +1,361 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
🥷 ПРОДВИНУТЫЙ STEALTH ПАРСЕР
|
||||
Максимальный обход защит для судебных сайтов
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from playwright.async_api import async_playwright
|
||||
import random
|
||||
import time
|
||||
|
||||
class AdvancedStealthParser:
|
||||
"""Парсер с максимальной маскировкой"""
|
||||
|
||||
# Реальные User-Agents
|
||||
USER_AGENTS = [
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
async def parse_with_human_behavior(url: str):
|
||||
"""
|
||||
МЕТОД 1: Имитация человеческого поведения
|
||||
"""
|
||||
print("═"*80)
|
||||
print("🧑 МЕТОД 1: ИМИТАЦИЯ ЧЕЛОВЕКА")
|
||||
print("═"*80)
|
||||
print()
|
||||
|
||||
async with async_playwright() as p:
|
||||
browser = await p.chromium.launch(
|
||||
headless=False, # НЕ headless - как настоящий браузер!
|
||||
args=[
|
||||
'--disable-blink-features=AutomationControlled',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-web-security',
|
||||
]
|
||||
)
|
||||
|
||||
context = await browser.new_context(
|
||||
user_agent=random.choice(AdvancedStealthParser.USER_AGENTS),
|
||||
viewport={'width': 1920, 'height': 1080},
|
||||
locale='ru-RU',
|
||||
timezone_id='Europe/Moscow',
|
||||
geolocation={'latitude': 55.7558, 'longitude': 37.6173}, # Москва
|
||||
permissions=['geolocation']
|
||||
)
|
||||
|
||||
page = await context.new_page()
|
||||
|
||||
# Скрываем автоматизацию
|
||||
await page.add_init_script("""
|
||||
Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
|
||||
Object.defineProperty(navigator, 'plugins', {get: () => [1, 2, 3]});
|
||||
window.chrome = {runtime: {}};
|
||||
""")
|
||||
|
||||
try:
|
||||
print("🌐 Загружаем страницу...")
|
||||
|
||||
# Медленно загружаем
|
||||
await page.goto(url, wait_until='domcontentloaded', timeout=30000)
|
||||
print(f"📊 Статус: {await page.title()}")
|
||||
|
||||
# ИМИТИРУЕМ ЧЕЛОВЕКА
|
||||
print("🖱️ Имитируем действия человека...")
|
||||
|
||||
# 1. Скроллим случайно
|
||||
await page.evaluate("window.scrollTo(0, 300)")
|
||||
await asyncio.sleep(random.uniform(1, 2))
|
||||
|
||||
await page.evaluate("window.scrollTo(0, 600)")
|
||||
await asyncio.sleep(random.uniform(1, 2))
|
||||
|
||||
# 2. Двигаем мышь
|
||||
await page.mouse.move(random.randint(100, 500), random.randint(100, 500))
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
# 3. Ждём дольше
|
||||
await asyncio.sleep(5)
|
||||
|
||||
# Получаем контент
|
||||
text = await page.inner_text('body')
|
||||
|
||||
print(f"✅ Получено {len(text)} символов")
|
||||
print()
|
||||
print("ПРЕВЬЮ:")
|
||||
print("-"*80)
|
||||
print(text[:500])
|
||||
print("-"*80)
|
||||
|
||||
return text
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка: {e}")
|
||||
return None
|
||||
finally:
|
||||
await browser.close()
|
||||
|
||||
@staticmethod
|
||||
async def parse_with_firefox(url: str):
|
||||
"""
|
||||
МЕТОД 2: Firefox (часто менее детектируемый)
|
||||
"""
|
||||
print("═"*80)
|
||||
print("🦊 МЕТОД 2: FIREFOX")
|
||||
print("═"*80)
|
||||
print()
|
||||
|
||||
async with async_playwright() as p:
|
||||
browser = await p.firefox.launch(headless=False)
|
||||
|
||||
context = await browser.new_context(
|
||||
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
|
||||
viewport={'width': 1920, 'height': 1080},
|
||||
locale='ru-RU'
|
||||
)
|
||||
|
||||
page = await context.new_page()
|
||||
|
||||
try:
|
||||
print("🌐 Загружаем через Firefox...")
|
||||
await page.goto(url, wait_until='networkidle', timeout=30000)
|
||||
|
||||
await asyncio.sleep(5)
|
||||
|
||||
text = await page.inner_text('body')
|
||||
print(f"✅ Получено {len(text)} символов")
|
||||
print()
|
||||
print("ПРЕВЬЮ:")
|
||||
print("-"*80)
|
||||
print(text[:500])
|
||||
print("-"*80)
|
||||
|
||||
return text
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка: {e}")
|
||||
return None
|
||||
finally:
|
||||
await browser.close()
|
||||
|
||||
@staticmethod
|
||||
async def parse_with_cookies(url: str):
|
||||
"""
|
||||
МЕТОД 3: С реальными cookies
|
||||
"""
|
||||
print("═"*80)
|
||||
print("🍪 МЕТОД 3: РЕАЛЬНЫЕ COOKIES")
|
||||
print("═"*80)
|
||||
print()
|
||||
print("💡 Для этого метода нужно:")
|
||||
print(" 1. Открыть сайт в обычном браузере")
|
||||
print(" 2. Экспортировать cookies")
|
||||
print(" 3. Передать их в парсер")
|
||||
print()
|
||||
|
||||
# Пример структуры
|
||||
print("Пример кода:")
|
||||
print("-"*80)
|
||||
print("""
|
||||
cookies = [
|
||||
{
|
||||
'name': 'session',
|
||||
'value': 'abc123...',
|
||||
'domain': '.mos-sud.ru',
|
||||
'path': '/'
|
||||
}
|
||||
]
|
||||
|
||||
context = await browser.new_context()
|
||||
await context.add_cookies(cookies)
|
||||
""")
|
||||
print("-"*80)
|
||||
|
||||
@staticmethod
|
||||
async def parse_step_by_step(url: str):
|
||||
"""
|
||||
МЕТОД 4: Пошаговая загрузка (сначала главная, потом целевая)
|
||||
"""
|
||||
print("═"*80)
|
||||
print("🪜 МЕТОД 4: ПОШАГОВАЯ ЗАГРУЗКА")
|
||||
print("═"*80)
|
||||
print()
|
||||
|
||||
async with async_playwright() as p:
|
||||
browser = await p.chromium.launch(
|
||||
headless=False,
|
||||
args=['--disable-blink-features=AutomationControlled']
|
||||
)
|
||||
|
||||
context = await browser.new_context(
|
||||
user_agent=random.choice(AdvancedStealthParser.USER_AGENTS),
|
||||
viewport={'width': 1920, 'height': 1080},
|
||||
locale='ru-RU'
|
||||
)
|
||||
|
||||
page = await context.new_page()
|
||||
|
||||
try:
|
||||
# Шаг 1: Главная страница
|
||||
print("📍 Шаг 1: Загружаем главную страницу...")
|
||||
await page.goto('https://mos-sud.ru/', wait_until='networkidle')
|
||||
await asyncio.sleep(3)
|
||||
print("✅ Главная загружена")
|
||||
|
||||
# Шаг 2: Переходим на нужную страницу
|
||||
print("📍 Шаг 2: Переходим на целевую страницу...")
|
||||
await page.goto(url, wait_until='networkidle', timeout=30000)
|
||||
await asyncio.sleep(5)
|
||||
|
||||
text = await page.inner_text('body')
|
||||
print(f"✅ Получено {len(text)} символов")
|
||||
print()
|
||||
print("ПРЕВЬЮ:")
|
||||
print("-"*80)
|
||||
print(text[:500])
|
||||
print("-"*80)
|
||||
|
||||
return text
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка: {e}")
|
||||
return None
|
||||
finally:
|
||||
await browser.close()
|
||||
|
||||
@staticmethod
|
||||
async def parse_with_delays(url: str):
|
||||
"""
|
||||
МЕТОД 5: Большие задержки между действиями
|
||||
"""
|
||||
print("═"*80)
|
||||
print("⏰ МЕТОД 5: МЕДЛЕННАЯ ЗАГРУЗКА")
|
||||
print("═"*80)
|
||||
print()
|
||||
|
||||
async with async_playwright() as p:
|
||||
browser = await p.chromium.launch(
|
||||
headless=False,
|
||||
slow_mo=500 # Замедляем ВСЕ действия
|
||||
)
|
||||
|
||||
context = await browser.new_context(
|
||||
user_agent=random.choice(AdvancedStealthParser.USER_AGENTS)
|
||||
)
|
||||
|
||||
page = await context.new_page()
|
||||
|
||||
try:
|
||||
print("🐌 Загружаем ОЧЕНЬ медленно (как человек)...")
|
||||
|
||||
await page.goto(url, wait_until='load', timeout=60000)
|
||||
print("⏳ Ждём 10 секунд...")
|
||||
await asyncio.sleep(10)
|
||||
|
||||
# Скроллим медленно
|
||||
for i in range(3):
|
||||
scroll_y = (i + 1) * 300
|
||||
await page.evaluate(f"window.scrollTo(0, {scroll_y})")
|
||||
await asyncio.sleep(2)
|
||||
|
||||
print("⏳ Ждём ещё 5 секунд...")
|
||||
await asyncio.sleep(5)
|
||||
|
||||
text = await page.inner_text('body')
|
||||
print(f"✅ Получено {len(text)} символов")
|
||||
print()
|
||||
print("ПРЕВЬЮ:")
|
||||
print("-"*80)
|
||||
print(text[:500])
|
||||
print("-"*80)
|
||||
|
||||
return text
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка: {e}")
|
||||
return None
|
||||
finally:
|
||||
await browser.close()
|
||||
|
||||
|
||||
async def test_all_methods(url: str):
|
||||
"""Тестируем все методы по очереди"""
|
||||
|
||||
print("🥷"*40)
|
||||
print()
|
||||
print(" ПРОДВИНУТЫЕ МЕТОДЫ ОБХОДА ЗАЩИТЫ")
|
||||
print()
|
||||
print("🥷"*40)
|
||||
print()
|
||||
print(f"Цель: {url}")
|
||||
print()
|
||||
input("⏸️ Нажми Enter чтобы начать тестирование...")
|
||||
print()
|
||||
|
||||
methods = [
|
||||
("Имитация человека", AdvancedStealthParser.parse_with_human_behavior),
|
||||
("Firefox", AdvancedStealthParser.parse_with_firefox),
|
||||
("Пошаговая загрузка", AdvancedStealthParser.parse_step_by_step),
|
||||
("Медленная загрузка", AdvancedStealthParser.parse_with_delays),
|
||||
]
|
||||
|
||||
results = {}
|
||||
|
||||
for name, method in methods:
|
||||
print()
|
||||
print("="*80)
|
||||
print(f"ТЕСТИРУЕМ: {name}")
|
||||
print("="*80)
|
||||
print()
|
||||
|
||||
try:
|
||||
result = await method(url)
|
||||
|
||||
if result and len(result) > 100:
|
||||
results[name] = "✅ УСПЕХ"
|
||||
if "77MS0312" in result or "дело" in result.lower():
|
||||
results[name] = "🎯 УСПЕХ (нашли данные!)"
|
||||
else:
|
||||
results[name] = "❌ Не удалось"
|
||||
except Exception as e:
|
||||
results[name] = f"❌ Ошибка: {e}"
|
||||
|
||||
print()
|
||||
input("⏸️ Нажми Enter для следующего метода...")
|
||||
|
||||
# Итоги
|
||||
print()
|
||||
print("="*80)
|
||||
print("📊 ИТОГОВЫЕ РЕЗУЛЬТАТЫ")
|
||||
print("="*80)
|
||||
print()
|
||||
|
||||
for name, result in results.items():
|
||||
print(f"{name:30s} {result}")
|
||||
|
||||
print()
|
||||
print("="*80)
|
||||
print()
|
||||
print("💡 ДОПОЛНИТЕЛЬНЫЕ МЕТОДЫ:")
|
||||
print()
|
||||
print("🍪 Cookies: Экспортируй cookies из реального браузера")
|
||||
print("🌐 Прокси: Используй residential прокси")
|
||||
print("🔐 VPN: Подключись через российский VPN")
|
||||
print("📧 API: Запроси официальный доступ к API суда")
|
||||
print()
|
||||
print("="*80)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
url = "https://mos-sud.ru/312/cases/civil/details/7b8a110a-162d-4493-88b0-e505523c9935?uid=77MS0312-01-2025-002929-35&formType=fullForm"
|
||||
|
||||
asyncio.run(test_all_methods(url))
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user