Промпт для Genspark | Team369

Промпт для Genspark | Team369

@teams_369

Скопируй промпт ниже и вставь в Genspark вместе с прикреплённым файлом исходных данных.

## Промпт


Прикрепляю файл с исходными данными. Это таблица с двумя столбцами (разделитель — табуляция): «Бренд» и «URL». В ней собраны результаты топ-3 Google SERP по различным брендам онлайн-казино (по 3 URL на каждый бренд).


Запусти приведённый ниже Python-скрипт. Он определит, по каким брендам в топ-3 SERP отсутствует официальный сайт продукта. Скрипт автоматически считает прикреплённый файл. Не меняй код, просто запусти.


```python

import subprocess, sys

try:

    import openpyxl

except ImportError:

    subprocess.check_call([sys.executable, "-m", "pip", "install", "openpyxl", "-q"])

    import openpyxl


import urllib.request

import urllib.error

import ssl

import re

import csv

import io

from urllib.parse import urlparse


# --- Домены-исключения (агрегаторы, обзорники, трастпилот и т.п.) ---

EXCLUDED_DOMAINS = [

    "trustpilot.com",

    "casino.guru",

    "askgamblers.com",

    "casinojager.com",

    "slotcatalog.com",

    "casinomeister.com",

    "vegasslotsonline.com",

    "wizardofodds.com",

    "casinoreviews.com",

]


# --- Футпринты официальных сайтов казино (SPA-скрипты) ---

FOOTPRINTS = [

    "s7s.ai",

    "contentdeliverynetwork.cc",

    "react-easyrocket",

    "modal-root",

    "react-hook-form",

    "libphonenumber",

]


# Признак SPA без контента

SPA_PATTERN = re.compile(r'<div\s+id=["\']root["\']\s*>\s*</div>', re.IGNORECASE)


# --- Футпринты SSR-казино (серверный рендеринг) ---

SSR_PATTERNS = [

    re.compile(r'/play/real/', re.IGNORECASE),

    re.compile(r'/casino/slot_games', re.IGNORECASE),

    re.compile(r'/casino/live_casino', re.IGNORECASE),

    re.compile(r'/sports\?page=', re.IGNORECASE),

]


# HTTP-клиент без прокси

ctx = ssl.create_default_context()

ctx.check_hostname = False

ctx.verify_mode = ssl.CERT_NONE

opener = urllib.request.build_opener(

    urllib.request.ProxyHandler({}),

    urllib.request.HTTPSHandler(context=ctx),

)



def is_official_site(url, timeout=15):

    result = {"url": url, "is_official": False, "reason": "", "status_code": None}


    if not url.startswith(("http://", "https://")):

        url = "https://" + url


    domain = urlparse(url).netloc.lower()

    for excluded in EXCLUDED_DOMAINS:

        if excluded in domain:

            result["reason"] = f"Исключён (агрегатор: {excluded})"

            return result


    req = urllib.request.Request(url, headers={

        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"

    })


    try:

        response = opener.open(req, timeout=timeout)

        result["status_code"] = response.status

        html = response.read().decode("utf-8", errors="replace")


        for fp in FOOTPRINTS:

            if fp in html:

                result["is_official"] = True

                result["reason"] = f"Найден маркер: {fp}"

                return result


        for pat in SSR_PATTERNS:

            if pat.search(html):

                result["is_official"] = True

                result["reason"] = f"SSR-казино: {pat.pattern}"

                return result


        if SPA_PATTERN.search(html):

            body_match = re.search(r"<body[^>]*>(.*)</body>", html, re.DOTALL)

            if body_match:

                body_text = re.sub(r"<[^>]+>", "", body_match.group(1)).strip()

                if len(body_text) < 100:

                    result["is_official"] = True

                    result["reason"] = "SPA без контента (скрипт)"

                    return result


        result["reason"] = "Признаки официального сайта не найдены"


    except urllib.error.HTTPError as e:

        result["status_code"] = e.code

        if e.code == 403:

            result["is_official"] = True

            result["reason"] = "HTTP 403 (гео-блокировка)"

        else:

            result["reason"] = f"HTTP {e.code} (не анализируется)"

    except urllib.error.URLError as e:

        result["reason"] = f"Ошибка соединения: {e.reason}"

    except TimeoutError:

        result["reason"] = "Таймаут"

    except Exception as e:

        result["reason"] = f"Ошибка: {str(e)}"


    return result



def read_input(file_path):

    rows = []


    # XLSX

    if file_path.lower().endswith((".xlsx", ".xls")):

        wb = openpyxl.load_workbook(file_path, read_only=True)

        ws = wb.active

        for row in ws.iter_rows(values_only=True):

            if not row or len(row) < 2:

                continue

            brand, url = str(row[0]).strip(), str(row[1]).strip()

            if not url.startswith("http") or brand.lower() in ("бренд", "brand"):

                continue

            rows.append({"brand": brand, "url": url})

        wb.close()

        return rows


    # Текстовые форматы (TSV, CSV, Markdown)

    with open(file_path, "r", encoding="utf-8") as f:

        content = f.read()


    for line in content.strip().splitlines():

        line = line.strip()

        if not line:

            continue

        # Markdown-таблица

        if line.startswith("|"):

            cells = [c.strip() for c in line.split("|")[1:-1]]

            if len(cells) >= 2:

                if cells[0].replace("-", "").replace(" ", "") == "" or cells[0].lower() in ("бренд", "brand"):

                    continue

                rows.append({"brand": cells[0], "url": cells[1]})

        # TSV / CSV

        elif "\t" in line:

            parts = line.split("\t", 1)

            if len(parts) == 2 and parts[1].startswith("http"):

                rows.append({"brand": parts[0].strip(), "url": parts[1].strip()})

        elif "," in line:

            parts = line.split(",", 1)

            if len(parts) == 2 and parts[1].strip().startswith("http"):

                rows.append({"brand": parts[0].strip(), "url": parts[1].strip()})

    return rows



# --- Чтение прикреплённого файла ---

import glob

import os


input_file = None

for pattern in ["/tmp/upload/*", "/tmp/*", "/uploads/*", "*.xlsx", "*.xls", "*.tsv", "*.csv", "*.md", "*.txt"]:

    files = glob.glob(pattern)

    for f in files:

        if os.path.isfile(f) and os.path.getsize(f) > 0:

            input_file = f

            break

    if input_file:

        break


if not input_file:

    print("Ошибка: не найден файл с входными данными. Прикрепи файл к сообщению.")

else:

    print(f"Файл: {input_file}")

    rows = read_input(input_file)

    brands = set(r["brand"] for r in rows)

    print(f"Загружено {len(rows)} строк, брендов: {len(brands)}")

    print("-" * 60)


    results = []

    for idx, row in enumerate(rows):

        brand, url = row["brand"], row["url"]

        print(f"  [{idx+1}/{len(rows)}] {brand} | {url} ... ", end="")

        check = is_official_site(url)

        check["brand"] = brand

        results.append(check)

        status = "✓ OFFICIAL" if check["is_official"] else "✗"

        print(f"{status} ({check['reason']})")


    brand_official = {}

    for r in results:

        b = r["brand"]

        if b not in brand_official:

            brand_official[b] = False

        if r["is_official"]:

            brand_official[b] = True


    no_official = [b for b, has in brand_official.items() if not has]


    print("\n" + "=" * 60)

    print(f"ИТОГО: брендов без официального сайта в топ-3: {len(no_official)}")

    print("=" * 60)


    print("\n| Бренд | URL | Оф. | Причина | HTTP |")

    print("|-------|-----|:---:|---------|:----:|")

    for r in results:

        o = "✓" if r["is_official"] else "✗"

        c = r["status_code"] if r["status_code"] else "—"

        print(f"| {r['brand']} | {r['url']} | {o} | {r['reason']} | {c} |")


    print(f"\n**Бренды без официального сайта в топ-3 ({len(no_official)}):**")

    if no_official:

        for b in no_official:

            print(f"- {b}")

    else:

        print("Все бренды имеют официальный сайт в топ-3.")

```


---


## Формат входного файла


Таблица с двумя столбцами: бренд и URL. Поддерживаемые форматы: **XLSX**, **TSV**, **CSV**, **Markdown**. Заголовки необязательны. Пример (TSV):


```

casino kokobet https://kokobet-nl.org/

casino kokobet https://www.casinojager.com/casinos/kokobet/

casino kokobet https://kokobets.nl/nl-1/

spin sino casino  https://www.spinsino.com/en

spin sino casino  https://spinsinos.nl/nl-nl1/

spin sino casino  https://spinsinocasino.org/nl/

```



Report Page