<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Vatican</title><generator>teletype.in</generator><description><![CDATA[Frontend architect]]></description><image><url>https://img1.teletype.in/files/41/40/4140a194-0637-4945-a19a-179a72b8cf29.png</url><title>Vatican</title><link>https://vatican-blog.cvv.life/</link></image><link>https://vatican-blog.cvv.life/?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vatican_joy</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/vatican_joy?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/vatican_joy?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Wed, 11 Nov 2026 09:48:22 GMT</pubDate><lastBuildDate>Wed, 11 Nov 2026 09:48:22 GMT</lastBuildDate><item><guid isPermaLink="true">https://vatican-blog.cvv.life/osint-map</guid><link>https://vatican-blog.cvv.life/osint-map?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vatican_joy</link><comments>https://vatican-blog.cvv.life/osint-map?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vatican_joy#comments</comments><dc:creator>vatican_joy</dc:creator><title>003 — OSINT: полная карта открытых источников</title><pubDate>Tue, 22 Sep 2026 01:08:31 GMT</pubDate><description><![CDATA[<img src="https://img1.teletype.in/files/46/08/4608ffc3-c5f6-4016-bfb2-be00a2789c9c.jpeg"></img>Всё, что можно узнать о человеке, фирме, месте и объекте — без единого запроса в закрытые базы]]></description><content:encoded><![CDATA[
  <blockquote id="CQOp"><em>Всё, что можно узнать о человеке, фирме, месте и объекте — без единого запроса в закрытые базы</em></blockquote>
  <h2 id="NUl3">Часть 1: Философия</h2>
  <p id="P13p">Ты оставляешь след везде. Каждый пост, фото, заказ, логин, маршрут. Эти данные <strong>уже публичны</strong> — просто разложены по сотням мест.</p>
  <p id="Eayx"><strong>OSINT</strong> — <em>искусство собирать эти куски в единую картину.</em></p>
  <ul id="91RD">
    <li id="tmZA">Фрагмент 1: ник на форуме</li>
    <li id="d5OC">Фрагмент 2: почта в утечке</li>
    <li id="P8YQ">Фрагмент 3: фото с геолокацией</li>
    <li id="h4D3">Фрагмент 4: номер телефона в объявлении</li>
    <li id="056q">Фрагмент 5: коммент в соцсети</li>
  </ul>
  <p id="32Jm">По отдельности — мусор.<br />Вместе — досье.</p>
  <hr />
  <h2 id="AyI8">Часть 2: Классификация</h2>
  <p id="u544"><em>OSINT делится на дисциплины. У каждой свои инструменты и методы.</em></p>
  <figure id="XJuJ" class="m_original">
    <img src="https://img1.teletype.in/files/84/b1/84b136e6-7aad-41cd-8499-ace83117204a.png" width="672" />
  </figure>
  <hr />
  <h2 id="jhfx">Часть 3: SOCMINT — человек через соцсети</h2>
  <h3 id="GYGH">Метод 1: Пивот от ника</h3>
  <blockquote id="9tAD"><em>Один ник почти всегда используется на десятках площадок. Это точка входа.</em></blockquote>
  <p id="lHmz"><strong>Инструменты:</strong></p>
  <ul id="mTuX">
    <li id="q1iA">WhatsMyName (web) — 600+ площадок</li>
    <li id="mDKS">Sherlock (CLI) — быстрый перебор</li>
    <li id="iYvA">Maigret (CLI) — Sherlock на стероидах</li>
    <li id="0dN3">Nexfil (CLI) — фокус на стриминг и киносайты</li>
    <li id="4yn7">Blackbird (CLI) — быстрый + поиск аккаунтов</li>
    <li id="unDq">ID Crawl — веб-интерфейс</li>
  </ul>
  <p id="6hsR"><strong>Sherlock в действии:</strong></p>
  <pre id="rog1" data-lang="python"># Установка
pip install sherlock-project

# Поиск ника на 400+ сайтах
sherlock vatican --timeout 10

# Результат:
# [+] GitHub: https://github.com/vatican
# [+] Telegram: https://t.me/vatican
# [+] Steam: https://steamcommunity.com/id/vatican
# [+] Reddit: https://reddit.com/user/vatican
# [+] SoundCloud: https://soundcloud.com/vatican</pre>
  <p id="lnbA"><strong>Maigret — глубже:</strong></p>
  <pre id="i1Ak" data-lang="python"># Поддерживает больше сайтов + вытаскивает доп. инфо
maigret vatican --html report

# Парсит аватарки, био, количество постов
# Генерирует HTML-отчёт со всеми найденными аккаунтами</pre>
  <h3 id="r4lD">Метод 2: Пивот от email</h3>
  <blockquote id="wSlK"><em>Почта — ключ к большинству сервисов.</em></blockquote>
  <p id="7q1e">Как пример:</p>
  <ul id="qMbf">
    <li id="Norg">Email → leaks → пароли</li>
    <li id="KpUb">Email → GitHub → код, коммиты, юзернейм</li>
    <li id="Ayc8">Email → Gravatar → аватар</li>
    <li id="4KOJ">Email → соцсети → восстановление → маска номера</li>
  </ul>
  <p id="BgCo"><strong>Агрегаторы email:</strong></p>
  <ul id="9GZ9">
    <li id="Z1HP">Epieos — покажет где зарегистрирован email</li>
    <li id="cqMW">EmailRep — репутация и возраст почты</li>
    <li id="HqtT">Holehe — проверка регистрации на 120+ сайтах</li>
  </ul>
  <p id="Eg4F"><strong>Holehe — где зарегистрирована почта:</strong></p>
  <pre id="PqcJ" data-lang="python">pip install holehe
holehe target@example.com

# [+] Instagram — зарегистрирован
# [+] Twitter — зарегистрирован
# [+] Spotify — зарегистрирован
# [+] Discord — зарегистрирован</pre>
  <h3 id="2w1H">Метод 3: Пивот от телефона</h3>
  <blockquote id="OTEz"><em>Номер телефона — это оператор, регион, и часто — имя.</em></blockquote>
  <ul id="7RKm">
    <li id="uYT0">Номер → оператор/регион → гео</li>
    <li id="G8WJ">Номер → Telegram → аватар, юзернейм, био</li>
    <li id="hZkN">Номер → мессенджеры (WhatsApp, Viber)</li>
    <li id="7R4j">Номер → объявления (Avito, Юла)</li>
    <li id="V9ag">Номер → утечки</li>
  </ul>
  <p id="a88w"><strong>Определение оператора и региона:</strong></p>
  <p id="NGC5"><em><u>Портация номеров между операторами делает определение оператора неточным</u></em></p>
  <pre id="uc2j" data-lang="python">import phonenumbers
from phonenumbers import carrier, geocoder, timezone

def analyze_phone(number_str):
    try:
        number = phonenumbers.parse(number_str, &quot;RU&quot;)
        
        if not phonenumbers.is_valid_number(number):
            return {&quot;valid&quot;: False}
        
        return {
            &quot;valid&quot;: True,
            &quot;country&quot;: geocoder.description_for_number(number, &quot;ru&quot;),
            &quot;carrier&quot;: carrier.name_for_number(number, &quot;ru&quot;),
            &quot;timezone&quot;: str(timezone.time_zones_for_number(number)),
            &quot;type&quot;: phonenumbers.number_type(number),
            &quot;formatted&quot;: phonenumbers.format_number(
                number, phonenumbers.PhoneNumberFormat.INTERNATIONAL
            )
        }
    except Exception as e:
        return {&quot;error&quot;: str(e)}</pre>
  <p id="Zt1q"><strong>Telegram как OSINT-инструмент:</strong></p>
  <ul id="g5pf">
    <li id="yDzx">Метод 1: Добавление в контакты<br />Telegram покажет: аватар, имя, юзернейм, био, последний раз онлайн</li>
    <li id="s7p6">Метод 2: через Telegram API<br />даже без сохранения контакта можно получить:<br />     - аватар<br />     - юзернейм<br />     - last seen<br />     - статус (был недавно/онлайн/офлайн)</li>
  </ul>
  <p id="UBOA"><strong>Пример использования:</strong></p>
  <p id="UEcB">api id и api hash можно получить тут <br /><a href="https://my.telegram.org/auth" target="_blank">https://my.telegram.org/auth</a></p>
  <pre id="oYF9" data-lang="python">from telethon.sync import TelegramClient

api_id = API_ID
api_hash = &quot;API_HASH&quot;

with TelegramClient(&quot;session&quot;, api_id, api_hash) as client:
    # Поиск по номеру
    contact = client.get_entity(&quot;+79991234567&quot;)
    
    print(f&quot;Имя: {contact.first_name} {contact.last_name}&quot;)
    print(f&quot;Юзернейм: @{contact.username}&quot;)
    print(f&quot;Телефон: {contact.phone}&quot;)
    print(f&quot;Статус: {contact.status}&quot;)
    
    # Скачать аватар
    client.download_profile_photo(contact, file=&quot;avatar.jpg&quot;)
    
    # Получить био
    full = client.get_entity(contact)
    print(f&quot;Био: {full.about}&quot;)</pre>
  <p id="e7h2"><strong>Определение наличия в мессенджерах:</strong></p>
  <ul id="eCl9">
    <li id="JbBs">truecaller — имя по номеру (платно, но есть триал)</li>
    <li id="Z0Ku">eyecon — то же</li>
    <li id="qN3e">GetContact — показывает как записан в контактах других</li>
    <li id="EPf7">NumBuster — аналогично</li>
  </ul>
  <h3 id="um2o">Метод 4: Кросс-корреляция</h3>
  <blockquote id="5dNt"><em>Самое мощное — когда данные из разных источников сходятся.</em></blockquote>
  <p id="730E">Пример пайплайна:</p>
  <p id="M6Uy">Ник &quot;vatican&quot;<br />  → Sherlock находит Twitter, GitHub, Telegram<br />  → GitHub → email в коммите → vatican@example.com<br />  → Holehe → почта зарегистрирована в VK, Avito<br />  → VK → настоящие имя и фамилия, город<br />  → Avito → телефон → пробив в Telegram<br />  → Telegram → настоящее фото → Google Images<br />  → Google Images → LinkedIn → место работы<br />  <br /><em><u>Итого: полное досье за 30 минут.</u></em></p>
  <hr />
  <h2 id="5wCI">Часть 4: GEOINT — геолокация</h2>
  <h3 id="DDVk">Метод 1: EXIF данные</h3>
  <blockquote id="pLfZ"><em>Каждое фото с телефона содержит метаданные — если автор их не вычистил.</em></blockquote>
  <pre id="Z0Mu" data-lang="python">from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
import requests

def extract_exif(image_path):
    image = Image.open(image_path)
    exif_data = image._getexif()
    
    if not exif_data:
        return {&quot;error&quot;: &quot;EXIF данные удалены или отсутствуют&quot;}
    
    data = {}
    for tag_id, value in exif_data.items():
        tag = TAGS.get(tag_id, tag_id)
        data[tag] = value
    
    # GPS координаты
    if &quot;GPSInfo&quot; in data:
        gps_info = data[&quot;GPSInfo&quot;]
        gps = {}
        for key in gps_info:
            decode = GPSTAGS.get(key, key)
            gps[decode] = gps_info[key]
        
        # Конвертация в десятичные градусы
        def dms_to_decimal(dms, ref):
            degrees = float(dms[0])
            minutes = float(dms[1])
            seconds = float(dms[2])
            decimal = degrees + minutes/60 + seconds/3600
            if ref in [&quot;S&quot;, &quot;W&quot;]:
                decimal = -decimal
            return decimal
        
 lat = dms_to_decimal(gps[&quot;GPSLatitude&quot;], gps.get(&quot;GPSLatitudeRef&quot;, &quot;N&quot;))
 lon = dms_to_decimal(gps[&quot;GPSLongitude&quot;], gps.get(&quot;GPSLongitudeRef&quot;, &quot;E&quot;))
        
        return {
            &quot;coordinates&quot;: (lat, lon),
            &quot;maps_link&quot;: f&quot;https://maps.google.com/?q={lat},{lon}&quot;,
            &quot;camera&quot;: data.get(&quot;Model&quot;),
            &quot;date&quot;: data.get(&quot;DateTimeOriginal&quot;),
            &quot;software&quot;: data.get(&quot;Software&quot;)
        }
    
    return {&quot;gps&quot;: &quot;нет GPS данных&quot;, &quot;meta&quot;: data}

# Что даёт EXIF:
# точные координаты съёмки
# модель телефона/камеры
# дату и время
# настройки съёмки
# иногда — серийный номер устройства</pre>
  <p id="mqm0"><strong>Проверка онлайн (без установки):</strong></p>
  <ul id="BB0X">
    <li id="zwtJ">exif.tools — просто загрузил увидел всё</li>
    <li id="4DSO">fotoforensics.com — анализ + детект фотошопа</li>
    <li id="5H8e">metapicz — аналогично</li>
  </ul>
  <h3 id="OWd7">Метод 2: Геолокация по фото без EXIF</h3>
  <blockquote id="14MD"><em>Когда метаданные вычищены — включается дедукция. Это уже ремесло.</em></blockquote>
  <p id="sgAz"><strong>Что смотреть на фото:</strong></p>
  <ul id="BIqy">
    <li id="XNow">Таблички (названия улиц, номера домов)</li>
    <li id="ANEf">Вывески (магазины, рестораны, названия)</li>
    <li id="GSbL">Язык надписей и шрифты</li>
    <li id="Td7s">Номерные знаки машин (формат, цвет, регион)</li>
    <li id="GFeR">Сторона движения (левостороннее/правостороннее)</li>
    <li id="955N">Архитектурный стиль</li>
    <li id="8PLu">Тип фонарей и разметки</li>
    <li id="b4wX">Положение солнца (время + полушарие)</li>
    <li id="sxLb">Провода (есть/нет, над/под землёй)</li>
    <li id="SD3J">Горы/море/рельеф на горизонте</li>
    <li id="obuO">Как уложена плитка/тротуар (положение/форма/материал/узор)</li>
  </ul>
  <p id="x8nc"><strong>Пошаговый процесс:</strong></p>
  <ol id="zsN3">
    <li id="nqYv">Обрати внимание на уникальные объекты</li>
    <li id="hy6U">Обратный поиск через Google Lens</li>
    <li id="3PwU">Открой Google Maps в этом регионе</li>
    <li id="py64">Включи Street View</li>
    <li id="HgXR">Совмещай панорамы с фото</li>
    <li id="ll1c">Ищи совпадения по ориентирам</li>
  </ol>
  <p id="nImS"><strong>Инструменты:</strong></p>
  <ul id="ybeC">
    <li id="NSQe">Google Lens — распознавание объектов и мест</li>
    <li id="rkvN">Yandex Images — часто лучше Google для СНГ</li>
    <li id="zyz3">Bing Visual Search — третий источник</li>
    <li id="9sJn">GeoGuessr — тренировка навыка (игра)</li>
    <li id="w3xJ">Mapillary — краудсорсинговый street view</li>
    <li id="I6bX">OpenStreetMap — детальные карты</li>
    <li id="WX2c">Sentinel Hub — спутниковые снимки</li>
    <li id="CQkF">SunCalc — положение солнца по времени/месту</li>
  </ul>
  <p id="3IqR"><strong>Пример метода &quot;солнце + тень&quot;:</strong></p>
  <p id="eDNo">Дано: фото без гео, с тенью от столба</p>
  <ol id="tMNN">
    <li id="q8On">Замерь угол тени относительно объекта</li>
    <li id="gIwD">Солнце движется с востока на запад</li>
    <li id="cSx6">Угол тени + время на фото (если есть) = широта</li>
    <li id="clk9">Сверяешь с картой</li>
  </ol>
  <p id="4TOG"><strong>Пример метода &quot;вывески&quot;:</strong></p>
  <p id="eKTN">Фото ресторана изнутри</p>
  <ol id="MybR">
    <li id="LRvo">Читаешь название на стакане &quot;Coffee Like&quot;</li>
    <li id="gZ0g">Ищешь &quot;Coffee Like&quot; на 2GIS в городе из контекста</li>
    <li id="cjwy">Открываешь панораму у каждого филиала</li>
    <li id="rT8m">Ищешь совпадение интерьера</li>
    <li id="6av9">Совпало → точная локация</li>
  </ol>
  <h3 id="piD4">Метод 3: Геолокация через поведение</h3>
  <blockquote id="MMvT"><em>Не фото, а цифровой след человека в пространстве.</em></blockquote>
  <p id="ECGq"><strong>Источники</strong>:</p>
  <ul id="YUkb">
    <li id="ejjU">Strava Heatmap — маршруты бегунов (палит военные базы)</li>
    <li id="6MDO">Instagram локации — чекины</li>
    <li id="pVSc">Fitness-трекеры — маршруты</li>
    <li id="Wa6s">Фото по тегам города — где бывает</li>
    <li id="IgQm">Отзывы на картах — Google/Yandex отзывы = места посещения</li>
    <li id="CCAf">Объявления — геолокация на Avito</li>
  </ul>
  <p id="JOO6"><strong>Strava Heatmap — классический пример:</strong></p>
  <p id="oXHU">Сервис публикует тепловую карту всех маршрутов пользователей. Через неё нашли:</p>
  <ul id="B9nf">
    <li id="mw6W">Секретные военные базы</li>
    <li id="9tFP">Маршруты охраны</li>
    <li id="iXP3">Личные адреса (дом → работа)</li>
  </ul>
  <h3 id="phy2">Метод 4: Спутниковые снимки</h3>
  <p id="Xaln">Инструменты:</p>
  <ul id="KKRq">
    <li id="7FBR">Google Earth Pro — бесплатно, история снимков</li>
    <li id="3UND">Sentinel Playground — свежие снимки (обновление каждые 5 дней)</li>
    <li id="dwkC">Bing Maps — иногда снимки лучше Google</li>
    <li id="SppS">Yandex Maps — для СНГ</li>
    <li id="0KvP">Terraserver — исторические снимки</li>
  </ul>
  <p id="z1NF"><strong>Что можно определить по спутнику:</strong></p>
  <ol id="VmcG">
    <li id="QesJ">Размер объекта и планировку</li>
    <li id="cQLh">Теневую сторону в разное время суток</li>
    <li id="GUNP">Историю (Google Earth хранит архив за 20+ лет)</li>
    <li id="wOjF">Транспорт и технику</li>
    <li id="5VlM">Недавние изменения (стройка, снос)</li>
  </ol>
  <hr />
  <h2 id="VNpc">Часть 5: IMINT — изображения</h2>
  <blockquote id="0D9U">Обратный поиск изображений</blockquote>
  <p id="4LSf"><strong>Движки и их сильные стороны:</strong></p>
  <ul id="sw7s">
    <li id="AOTI">Google Images — Универсальный, глобальный</li>
    <li id="xoBN">Yandex Images — СНГ, лица, лучше всех ищет по людям</li>
    <li id="Ngb6">Bing Visual — Промтовары, продукты</li>
    <li id="SUPx">TinEye — Точное совпадение, история</li>
    <li id="5kP3">PimEyes — Поиск по лицу (найти все фото человека)</li>
    <li id="YE90">FaceCheck.ID — Поиск по лицу в криминальном контексте</li>
    <li id="OvPU">百度 (Baidu) — Азия</li>
  </ul>
  <p id="s4Yk"><strong>PimEyes — поиск лица:</strong></p>
  <p id="2Mhz">Загружаешь фото человека</p>
  <ol id="43Nm">
    <li id="zZqK">движок сканирует веб</li>
    <li id="95s5">показывает ВСЕ фото этого лица в открытом доступе</li>
    <li id="7Uuz">даже те, где нет тега или имени</li>
  </ol>
  <blockquote id="313A"><em>Это самый мощный инструмент деанона через визуал. Есть и обратная сторона — работает в обе стороны.</em></blockquote>
  <h3 id="b9nC">Автоматизация обратного поиска:</h3>
  <pre id="O29Y" data-lang="python"># Яндекс Images — автоматический обратный поиск
import requests
from io import BytesIO

def yandex_reverse_search(image_path):
    url = &quot;https://yandex.ru/images/search&quot;
    
    files = {&quot;upfile&quot;: (&quot;image.jpg&quot;, open(image_path, &quot;rb&quot;), &quot;image/jpeg&quot;)}
    params = {&quot;rpt&quot;: &quot;imageview&quot;, &quot;cbird&quot;: &quot;77&quot;}
    
    session = requests.Session()
    response = session.post(url, params=params, files=files)
    
    
    return response.url  # ссылка на результаты поиска

# Для продакшена лучше использовать:
# - SerpAPI (платно, стабильно)
# - Browser automation (Playwright)</pre>
  <hr />
  <h2 id="xbm4">Часть 6: TECHINT — инфраструктура</h2>
  <blockquote id="0lcb">Домены и IP </blockquote>
  <p id="zgMH"><strong>Инструменты:</strong></p>
  <ul id="aPSM">
    <li id="Hdr1">whois — владелец домена, регистратор</li>
    <li id="O8fY">DNSDumpster — вся DNS-структура</li>
    <li id="00On">Shodan — поисковик по устройствам в сети</li>
    <li id="eguF">Censys — аналог Shodan</li>
    <li id="V0zb">SecurityTrails — история DNS, субдомены</li>
    <li id="yIUA">crt.sh — SSL сертификаты и субдомены</li>
    <li id="aFMB">ViewDNS — обратный IP (кто ещё на этом IP)</li>
    <li id="INRA">Hunter.io — email на домене</li>
  </ul>
  <p id="6pPU"><strong>Shodan — поиск устройств:</strong></p>
  <pre id="2xg8" data-lang="python">import shodan

api = shodan.Shodan(&quot;API_KEY&quot;)

# Поиск открытых камер
results = api.search(&#x27;webcam city:Moscow&#x27;)

for result in results[&#x27;matches&#x27;]:
    print(f&quot;IP: {result[&#x27;ip_str&#x27;]}&quot;)
    print(f&quot;Port: {result[&#x27;port&#x27;]}&quot;)
    print(f&quot;Org: {result.get(&#x27;org&#x27;)}&quot;)
    print(f&quot;Location: {result[&#x27;location&#x27;]}&quot;)
    print(&quot;---&quot;)

# Поиск незащищённых баз данных
results = api.search(&#x27;mongodb port:27017&#x27;)

# Поиск по IP — вся информация об устройстве
host = api.host(&#x27;8.8.8.8&#x27;)
print(host)</pre>
  <p id="OreA"><strong>crt.sh — скрытые субдомены через SSL:</strong></p>
  <pre id="HnCz" data-lang="python"># Все SSL сертификаты, выданные для домена
curl -s &quot;https://crt.sh/?q=%25.example.com&amp;output=json&quot; | \
  jq -r &#x27;.[].name_value&#x27; | sort -u

# Результат — все субдомены, которые когда-либо выпускали серт</pre>
  <p id="bPfM"><strong>Полный OSINT по домену:</strong></p>
  <pre id="dxFN" data-lang="python">import requests
import whois
from dns import resolver

def full_domain_recon(domain):
    report = {}
    
    # WHOIS
    try:
        w = whois.whois(domain)
        report[&quot;registrar&quot;] = w.registrar
        report[&quot;created&quot;] = str(w.creation_date)
        report[&quot;owner&quot;] = w.name  # если не скрыт privacy
    except:
        pass
    
    # DNS записи
    for record_type in [&quot;A&quot;, &quot;MX&quot;, &quot;NS&quot;, &quot;TXT&quot;]:
        try:
            answers = resolver.resolve(domain, record_type)
            report[record_type] = [str(r) for r in answers]
        except:
            pass
    
    # Субдомены через crt.sh
    try:
        resp = requests.get(
            f&quot;https://crt.sh/?q=%25.{domain}&amp;output=json&quot;,
            timeout=10
        )
        subdomains = set()
        for entry in resp.json():
            for name in entry[&quot;name_value&quot;].split(&quot;\n&quot;):
                if domain in name:
                    subdomains.add(name.strip())
        report[&quot;subdomains&quot;] = list(subdomains)
    except:
        pass
    
    # Email через Hunter.io
    # (нужен API ключ, бесплатный тариф — 25 запросов/мес)
    
    return report</pre>
  <hr />
  <h2 id="q47N">Часть 7: Утечки данных</h2>
  <h3 id="hnYY">Проверка своих данных</h3>
  <ul id="emWT">
    <li id="7TFX">HaveIBeenPwned — email + пароли (проверка по K-Anonymity)</li>
    <li id="3bB9">DeHashed — полный поиск по утечкам (email, имя, IP, телефон)</li>
    <li id="KBPp">LeakCheck — email/телефон/ник</li>
    <li id="EisM">Snusbase — самый быстрый (платный)</li>
    <li id="LuIp">Intelligence X — darknet + утечки</li>
  </ul>
  <h3 id="kjwx">Что дают утечки:</h3>
  <ul id="yxcy">
    <li id="07ry">Email + пароль → доступ к аккаунтам (если пароль не уникальный)</li>
    <li id="s8wy">Email + телефон → связка для деанона</li>
    <li id="TUad">Email + адрес → физическая локация</li>
    <li id="Pfwk">Email + паспортные данные → полный профиль</li>
  </ul>
  <p id="NP5c"><strong>Пример работы с DeHashed API:</strong></p>
  <pre id="lIYH" data-lang="python">import requests
import base64

def dehashed_search(query, email, api_key):
    # Поиск по всем утечкам
    auth = base64.b64encode(f&quot;{email}:{api_key}&quot;.encode()).decode()
    
    headers = {
        &quot;Accept&quot;: &quot;application/json&quot;,
        &quot;Authorization&quot;: f&quot;Basic {auth}&quot;
    }
    
    # Поиск можно вести по:
    # email, username, name, address, phone, ip, hash
    
    response = requests.get(
        f&quot;https://api.dehashed.com/search?query=email:{query}&quot;,
        headers=headers
    )
    return response.json()

# Результат содержит:
# - все пароли (в чистом/хешированном виде)
# - все email
# - имена
# - адреса
# - телефоны
# - IP</pre>
  <hr />
  <h2 id="doci">Часть 8: Транспорт и физический мир</h2>
  <blockquote id="oDUG">Номера автомобилей</blockquote>
  <p id="ea2Y">Формат российского номера:<br /><em><u>А123ВС77 регион 77, Москва</u></em></p>
  <p id="OgRm">Источники:</p>
  <ul id="hLLK">
    <li id="IYQ7">ГИБДД (гибдд.рф) — история ДТП</li>
    <li id="5wDM">Автокод (avtocod.ru) — платный агрегатор</li>
    <li id="iXBF">Номер-база — платные Telegram-боты</li>
    <li id="r73r">Реестр залогов (reestr-zalogov.ru) — залог</li>
    <li id="Kq8S">ФССП — если есть долги владельца</li>
  </ul>
  <h3 id="JJBA">Авиация</h3>
  <ul id="aUo4">
    <li id="WOgp">Flightradar24  — все рейсы в реальном времени</li>
    <li id="wVRe">ADS-B Exchange — без фильтров (в отличие от FR24)</li>
    <li id="5t4p">OpenSky Network — открытое API</li>
  </ul>
  <p id="QVaC"><strong>Отслеживание частного борта:</strong></p>
  <pre id="qVt8" data-lang="python">import requests

def track_aircraft(callsign):
    response = requests.get(
        f&quot;https://opensky-network.org/api/states/all?callsign={callsign}&quot;
    )
    data = response.json()
    
    if data.get(&quot;states&quot;):
        for state in data[&quot;states&quot;]:
            return {
                &quot;callsign&quot;: state[1],
                &quot;latitude&quot;: state[6],
                &quot;longitude&quot;: state[5],
                &quot;altitude&quot;: state[13],
                &quot;velocity&quot;: state[9],
                &quot;heading&quot;: state[10],
                &quot;on_ground&quot;: state[8]
            }
    return None</pre>
  <h3 id="afBi">Морской транспорт</h3>
  <ul id="4bcE">
    <li id="vbQY">MarineTraffic — все суда</li>
    <li id="BTHo">VesselFinder — аналог</li>
  </ul>
  <hr />
  <h2 id="rYIm">Часть 9: Автоматизация — фреймворки</h2>
  <h3 id="83u3">SpiderFoot — автоматический OSINT-скан</h3>
  <pre id="f2IF" data-lang="python"># Установка
pip install spiderfoot

# Запуск веб-интерфейса
sf -l 127.0.0.1:5001

# Скан по email
sf -s target@example.com -t all

# Скан по IP
sf -s 8.8.8.8 -t all

# Скан по домену
sf -s example.com -t all</pre>
  <blockquote id="CcoL"><em>SpiderFoot автоматически прогоняет цель через 200+ модулей и собирает всё в один отчёт.</em></blockquote>
  <h3 id="mUlU">Maltego — визуальный OSINT</h3>
  <pre id="NxPJ">Построение графов связей:
Цель → запросы к разным источникам → визуальные связи

Пример графа:
  Email
  ├── Twitter аккаунт
  │   └── Подписки → другие аккаунты
  ├── Домены (whois)
  │   └── Другие домены на тот же whois
  ├── Утечки
  └── Соцсети

Платный, но Community-версия достаточна для старта.</pre>
  <h3 id="lSrt">TheHarvester — сбор email/субдоменов</h3>
  <pre id="tlRG" data-lang="python"># Сбор email с домена из публичных источников
theHarvester -d example.com -b all

# Источники:
# - поисковые системы
# - LinkedIn
# - сертификаты
# - DNS</pre>
  <hr />
  <h2 id="Sd2t">Часть 10: OpSec исследователя</h2>
  <blockquote id="vscE"><em>Пока ты копаешь — тебя тоже могут копать.</em></blockquote>
  <p id="RIil"><strong>Правила гигиены:</strong></p>
  <ul id="2QHU">
    <li id="zlfz">Никогда не логинься в свои аккаунты при исследовании</li>
    <li id="yXLV">Используй отдельный браузер (профиль) для OSINT</li>
    <li id="zflV">SOCKS5 / VPN — не для анонимности, для смены IP</li>
    <li id="2wRX">Виртуалка для рискованных сайтов</li>
    <li id="2w2c">Не открывай ссылки напрямую — скрин через сервисы</li>
    <li id="Fn91">Не переходи по ссылкам из подозрительных сообщений</li>
    <li id="KA7e">Отключи синхронизацию браузера</li>
    <li id="KP11">Отдельная почта для регистраций при исследовании</li>
  </ul>
  <p id="JZuA"><strong>Инструменты безопасного просмотра:</strong></p>
  <ul id="xYU5">
    <li id="MGMq">urlscan.io — скриншот сайта без захода на него</li>
    <li id="dQLT">archive.org — просмотр старой версии</li>
    <li id="DlEp">proxy — через прокси для смены IP</li>
    <li id="fkCC">whonix — виртуалка с Tor</li>
  </ul>
  <hr />
  <h2 id="Zc1z">Часть 11: Как НЕ надо</h2>
  <ul id="TfCq">
    <li id="20LL">Сталкинг бывших/близких — это незаконно и аморально XD)</li>
    <li id="pj1x">Скачивание данных из взломанных баз (кроме проверки своих)</li>
    <li id="1svC">Попытки взлома на основе собранной информации</li>
    <li id="qwrT">Публикация собранных данных без согласия</li>
    <li id="SWem">Пробив через &quot;серые&quot; Telegram-боты (палевно и небезопасно)</li>
    <li id="Xzn5">Использование OSINT для шантажа</li>
  </ul>
  <blockquote id="F0gE"><strong><em>OSINT — это про понимание системы. Будь умнее чем просто шантажировать и публиковать просто так) </em></strong></blockquote>
  <blockquote id="d6m0"><em>By Vatican</em></blockquote>

]]></content:encoded></item><item><guid isPermaLink="true">https://vatican-blog.cvv.life/Reality_Reversal</guid><link>https://vatican-blog.cvv.life/Reality_Reversal?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vatican_joy</link><comments>https://vatican-blog.cvv.life/Reality_Reversal?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vatican_joy#comments</comments><dc:creator>vatican_joy</dc:creator><title>Reality Reversal</title><pubDate>Fri, 18 Sep 2026 10:20:25 GMT</pubDate><category>Dev</category><description><![CDATA[<img src="https://img3.teletype.in/files/66/e8/66e89196-e734-482b-88a1-d1734b4208da.jpeg"></img>В 1986 году The Mentor написал &quot;Сознание хакера&quot;. Прошло почти 40 лет. Мир изменился. Мы — нет.]]></description><content:encoded><![CDATA[
  <p id="GvkA"><em>В 1986 году The Mentor написал &quot;Сознание хакера&quot;. Прошло почти 40 лет. Мир изменился. Мы — нет.</em></p>
  <blockquote id="LTti"><strong>Мы верим, что:</strong><br /><strong>Знание — это власть. Не доступ к власти. Не инструмент власти. Сама власть.</strong></blockquote>
  <blockquote id="TV69"><strong><br />Тот, кто понимает механику системы — контролирует её. Тот, кто контролирует — не спрашивает разрешения.</strong></blockquote>
  <h3 id="G11s">Наши принципы:<br />1. Разбирай всё</h3>
  <blockquote id="74ct"><em>Всё, что построено — можно разобрать. Всё, что работает — можно понять. Всё, что можно понять — можно воспроизвести. Нет &quot;закрытых&quot; систем. Есть системы, которые ты ещё не вскрыл.</em></blockquote>
  <h3 id="3e73">2. Поверхность — это ложь</h3>
  <blockquote id="TDR4"><em>То, что показывают — витрина. То, что под ней — сущность. API скрыт? Значит есть. Данные &quot;недоступны&quot;? Значит просто не нашли endpoint. Реальность имеет слои, и большинство живёт на первом.</em></blockquote>
  <h3 id="nlkw">3. Слабость системы — не твоя проблема</h3>
  <blockquote id="1bWH"><em>Если их пароль — 123456. Если их API отдаёт всё без токена. Если их &quot;защита&quot; — проверка на фронте. Это не ты эксплуатируешь. Это они построили картонный дом.</em></blockquote>
  <h3 id="kp1a">4. Инструмент не выбирает цель</h3>
  <blockquote id="mN0d"><em>Молоток не решает, что строить. Скрипт не решает, что парсить. Тот, кто держит инструмент в руках — определяет применение.</em></blockquote>
  <h3 id="oSfT">5. Эффективность — единственная метрика</h3>
  <blockquote id="QlQ1"><em>Работает / не работает. Быстро / медленно. Обнаружили / не обнаружили. Остальное — шум.</em></blockquote>
  <h2 id="6tmV">Три типа тех, кто в этой игре:</h2>
  <ol id="aCky">
    <li id="HovK">Играет по правилам, которые написал кто-то другой. Ждёт bug bounty. Отчитывается. Просит.</li>
    <li id="c75z">Берёт что находит. Не спрашивает. Не оглядывается. Иногда проигрывает.</li>
    <li id="dHkt">Понимает обе стороны. Использует ту, которая даёт результат. Границу двигает под задачу.</li>
  </ol>
  <blockquote id="ZoKA"><em>Этот канал — не про этику. Не про закон. Не про &quot;как правильно&quot;.<br />Этот канал — про то, <strong>как всё устроено на самом деле</strong>.<br />Система видит то, что показывает. Мы видим то, что она скрывает.</em></blockquote>
  <blockquote id="CO9o"><em>By Vatican</em></blockquote>

]]></content:encoded></item><item><guid isPermaLink="true">https://vatican-blog.cvv.life/dark_side_API</guid><link>https://vatican-blog.cvv.life/dark_side_API?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vatican_joy</link><comments>https://vatican-blog.cvv.life/dark_side_API?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vatican_joy#comments</comments><dc:creator>vatican_joy</dc:creator><title>Тёмная сторона API</title><pubDate>Fri, 18 Sep 2026 10:05:36 GMT</pubDate><category>Dev</category><description><![CDATA[<img src="https://img1.teletype.in/files/01/6e/016ea2aa-72cf-471c-a2cf-4d19958edb59.jpeg"></img>Всё, что ты видишь в браузере — это данные. Вопрос только в том, как их достать.]]></description><content:encoded><![CDATA[
  <h2 id="2dNy">Часть 1: Анатомия данных</h2>
  <p id="iAAF"><em>Всё, что ты видишь в браузере — это данные. Вопрос только в том, как их достать.</em></p>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="xhNT">Сайт в браузере</p>
    <ul id="ClcM">
      <li id="20dt">Открытый API (мб будет документация)</li>
      <li id="Ni6w">Скрытый API (документации нету но стучать можно)</li>
      <li id="MasQ"><em>GraphQL endpoint</em></li>
      <li id="sulH"><em>WebSocket поток</em></li>
      <li id="qB0c"><em>Серверный рендеринг (HTML с данными)</em></li>
      <li id="yeVV"><em>Клиентский рендеринг (JS собирает данные)</em></li>
      <li id="5KC9"><em>Скрытые поля, комментарии, метаданные</em></li>
    </ul>
  </section>
  <blockquote id="TAjH"><strong><em><u>Если данные видны в браузере — их можно достать программно.</u></em></strong></blockquote>
  <h2 id="Ut8t">Часть 2: Уровни доступа к данным</h2>
  <h3 id="6e9S"><em>Уровень 0 — Официальное API</em></h3>
  <blockquote id="dV37">Самое простое. Документация открыта, ключ бесплатный.</blockquote>
  <pre id="lZlU" data-lang="python">import requests
# Пример: публичное API

response = requests.get(&quot;https://api.example.com/v1/data&quot;)
data = response.json()</pre>
  <p id="t15K"><strong>Плюсы:</strong> Стабильно, легально, документация<br /><strong>Минусы:</strong> Rate limits, неполные данные, ключ могут отозвать</p>
  <h3 id="wTVY">Уровень 1 — Скрытый API (Reverse Engineering)</h3>
  <p id="vl3c"><em>Сайты часто имеют внутренние API, которые фронтенд использует для получения данных. Документации нет, но endpoint работает.</em></p>
  <p id="fLPD"><strong>Как найти:</strong></p>
  <ol id="460M">
    <li id="DQ6B">Открой DevTools (F12)</li>
    <li id="btoM">Вкладка Network → XHR/Fetch</li>
    <li id="bf3G">Обнови страницу</li>
    <li id="r5yX">Смотри какие запросы летят</li>
    <li id="teu4">Найди endpoint с нужными данными</li>
  </ol>
  <p id="xaPM"></p>
  <blockquote id="VLOE"><strong>Пример — что видишь в Network:<br />GET https://site.com/api/v2/products?page=1&amp;limit=50</strong></blockquote>
  <p id="cr5e"></p>
  <p id="y1Pp"><strong>Воспроизводим</strong></p>
  <pre id="2O5i" data-lang="python">import requests

headers = {
    &quot;Authorization&quot;: &quot;Bearer eyJhbGciOiJIUzI1...&quot;,
    &quot;User-Agent&quot;: &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64)&quot;,
    &quot;Accept&quot;: &quot;application/json&quot;,
    &quot;Referer&quot;: &quot;https://site.com/catalog&quot;
}

response = requests.get(
    &quot;https://site.com/api/v2/products&quot;,
    params={&quot;page&quot;: 1, &quot;limit&quot;: 50},
    headers=headers
)
print(response.json())</pre>
  <p id="rX4d"></p>
  <p id="x0vv"><strong>Инструменты для реверса:</strong></p>
  <ul id="UJ66">
    <li id="kjfo"><strong>DevTools (Network)</strong> — базовый</li>
    <li id="SGLH"><strong>mitmproxy</strong> — перехват трафика мобильных приложений</li>
    <li id="mGkA"><strong>Charles Proxy</strong> — то же, но с GUI</li>
    <li id="uzck"><strong>Postman</strong> — тестирование найденных endpoints</li>
    <li id="Rw3d"><strong>Frida</strong> — хук методов в мобильных приложениях</li>
    <li id="IbZ1"><strong>Burp Suite — </strong>Позволяет перехватывать, анализировать и модифицировать HTTP- и HTTPS-трафик между браузером</li>
  </ul>
  <h3 id="TAw5">Уровень 2 — GraphQL Endpoints</h3>
  <blockquote id="LKJH"><em>Многие современные сайты используют GraphQL. Он отдаёт ровно те данные, которые запросишь.</em></blockquote>
  <p id="nrEd"><strong>Как обнаружить:</strong></p>
  <ol id="s1he">
    <li id="r7Rz">В DevTools ищи POST-запросы на /graphql</li>
    <li id="5s3u">Или /api/graphql</li>
    <li id="48N5">Или любые POST с query в body</li>
  </ol>
  <p id="iCtC"></p>
  <p id="OfEu"><strong>Интроспекция — всей схемы:</strong></p>
  <pre id="4XUC" data-lang="graphql"># Запрос всей схемы API
{
  __schema {
    types {
      name
      fields {
        name
        type {
          name
        }
      }
    }
  }
}</pre>
  <p id="7R2v"><strong>Пример запроса данных:</strong></p>
  <pre id="ozaX" data-lang="python">import requests

query = &quot;&quot;&quot;
{
  users(first: 100) {
    id
    username
    email
    posts {
      title
      createdAt
    }
  }
}
&quot;&quot;&quot;

response = requests.post(
    &quot;https://site.com/graphql&quot;,
    json={&quot;query&quot;: query},
    headers={&quot;Content-Type&quot;: &quot;application/json&quot;}
)
print(response.json())</pre>
  <p id="H7bc"><strong>Инструменты:</strong></p>
  <ul id="ZWR8">
    <li id="Cd5c"><strong>GraphiQL / Altair</strong> — IDE для GraphQL</li>
    <li id="Ey4b"><strong>graphql-path-enum</strong> — перебор скрытых полей</li>
    <li id="hCP0"><strong>InQL (Burp extension)</strong> — автоматическая интроспекция</li>
  </ul>
  <p id="DmHI"></p>
  <h3 id="5uYi">Уровень 3 — Парсинг HTML</h3>
  <blockquote id="uJ2c"><em>Когда API нет или оно закрыто — парсим то, что видит браузер.</em></blockquote>
  <h4 id="d9Em">Базовый — requests + BeautifulSoup</h4>
  <pre id="RXvG" data-lang="python">import requests
from bs4 import BeautifulSoup

response = requests.get(&quot;https://example.com/products&quot;)
soup = BeautifulSoup(response.text, &quot;html.parser&quot;)

products = soup.find_all(&quot;div&quot;, class_=&quot;product-card&quot;)

for product in products:
    title = product.find(&quot;h3&quot;).text.strip()
    price = product.find(&quot;span&quot;, class_=&quot;price&quot;).text
    link = product.find(&quot;a&quot;)[&quot;href&quot;]
    
    print(f&quot;{title} | {price} | {link}&quot;)</pre>
  <p id="rp9o"><strong>или когда например html динамический</strong></p>
  <pre id="hCHV" data-lang="python">from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    
    # Перехватываем API-запросы страницы
    responses = []
    page.on(&quot;response&quot;, lambda res: responses.append(res) 
            if &quot;api&quot; in res.url else None)
    
    page.goto(&quot;https://example.com/catalog&quot;)
    page.wait_for_load_state(&quot;networkidle&quot;)
    
    # Данные из перехваченных API-запросов
    for res in responses:
        print(res.url, res.json())
    
    # Или контент из DOM
    content = page.content()
    browser.close()
</pre>
  <h4 id="aYBE">Селекторы — что использовать</h4>
  <pre id="VGxd" data-lang="python"># CSS селекторы (быстрее, чище)
soup.select(&quot;div.product-card &gt; h3.title&quot;)
soup.select(&quot;a[href*=&#x27;/product/&#x27;]&quot;)
soup.select(&quot;span[data-price]&quot;)

# XPath (мощнее для сложной логики)
soup.xpath(&quot;//div[@class=&#x27;item&#x27;][position() &lt; 10]&quot;)
soup.xpath(&quot;//a[contains(@href, &#x27;product&#x27;)]/@href&quot;)</pre>
  <p id="9Gpm"></p>
  <h3 id="om4n">Уровень 4 — Headless Browser (эмуляция)</h3>
  <blockquote id="vDSs"><em>Когда сайт проверяет JS, куки, поведение — эмулируем реального пользователя.</em></blockquote>
  <h4 id="xOAR">Playwright — стандарт</h4>
  <pre id="wGfa" data-lang="python">from playwright.sync_api import sync_playwright
import time
import random

with sync_playwright() as p:
    browser = p.chromium.launch(
        headless=False,
        args=[
            &quot;--disable-blink-features=AutomationControlled&quot;,
            &quot;--no-sandbox&quot;
        ]
    )
    
    context = browser.new_context(
        viewport={&quot;width&quot;: 1920, &quot;height&quot;: 1080},
        user_agent=&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36&quot;,
        locale=&quot;ru-RU&quot;,
        timezone_id=&quot;Europe/Moscow&quot;
    )
    
    page = context.new_page()
    
    # Убираем флаг webdriver
    page.add_init_script(&quot;&quot;&quot;
        Object.defineProperty(navigator, &#x27;webdriver&#x27;, {
            get: () =&gt; undefined
        });
    &quot;&quot;&quot;)
    
    page.goto(&quot;https://example.com&quot;)
    
    # Имитируем человека
    time.sleep(random.uniform(1, 3))
    page.mouse.move(random.randint(100, 800), random.randint(100, 600))
    
    # Скроллим как человек
    page.evaluate(&quot;&quot;&quot;
        async () =&gt; {
            for (let i = 0; i &lt; document.body.scrollHeight; i += 100) {
                window.scrollTo(0, i);
                await new Promise(r =&gt; setTimeout(r, 100));
            }
        }
    &quot;&quot;&quot;)
    
    # Забираем контент
    html = page.content()
    
    browser.close()</pre>
  <h4 id="KV3h">Анти-детект: что проверяют сайты (зависит от фантазии создателя)</h4>
  <p id="jCd5">Основное</p>
  <figure id="erw2" class="m_original">
    <img src="https://img1.teletype.in/files/4e/73/4e73ec50-6381-4ab8-b555-e71c7e38d889.png" width="568" />
  </figure>
  <h3 id="wF0M">Уровень 5 — Мобильные API</h3>
  <blockquote id="t3ii"><em>Приложения часто используют API, недоступные через веб. Данные там чище и полнее.</em></blockquote>
  <p id="rOhj"><strong>Инструменты:</strong></p>
  <ul id="UzEO">
    <li id="56Bc">mitmproxy — перехват HTTPS трафика</li>
    <li id="vB4u">Frida — инъекция кода в приложение</li>
    <li id="Ghsm">Charles Proxy — GUI-альтернатива</li>
    <li id="NHWg">jadx — декомпиляция APK</li>
  </ul>
  <p id="fb7P"><strong>Процесс:</strong></p>
  <ol id="eIui">
    <li id="tdC5">Скачай APK (apkpure, apkmirror)</li>
    <li id="1WY7">Декомпилируй (jadx)</li>
    <li id="YK5I">Ищи строки с &quot;api&quot;, &quot;http&quot;, &quot;endpoint&quot;</li>
    <li id="qKnM">Найди базовый URL и параметры</li>
    <li id="BXQf">Перехвати трафик через mitmproxy</li>
    <li id="wfFf">Воспроизведи запрос в Python</li>
  </ol>
  <h2 id="31ho"><strong>Часть 3: Защита и обход</strong></h2>
  <h3 id="lkcQ">Rate Limiting</h3>
  <p id="E9wD">Сайт ограничивает частоту запросов. Виды:</p>
  <ul id="Yo3o">
    <li id="NSGv">IP-based → ротация прокси</li>
    <li id="19sT">API Key-based → ротация ключей</li>
    <li id="PjYU">Session-based → ротация сессий</li>
    <li id="GOgj">Cookie-based → сброс куки</li>
    <li id="XyCR">Device fingerprint → подмена отпечатка</li>
  </ul>
  <p id="0YE5"><strong>Подход:</strong></p>
  <pre id="nLU3" data-lang="python">import time
import random
from itertools import cycle

class RateLimiter:
    def __init__(self, min_delay=1.0, max_delay=3.0):
        self.min_delay = min_delay
        self.max_delay = max_delay
    
    def wait(self):
        delay = random.uniform(self.min_delay, self.max_delay)
        time.sleep(delay)

# Использование прокси
proxies = cycle([
    &quot;http://proxy1:port&quot;,
    &quot;http://proxy2:port&quot;,
    &quot;http://proxy3:port&quot;,
])

limiter = RateLimiter(1, 3)

for url in urls:
    proxy = next(proxies)
    limiter.wait()
    
    response = requests.get(url, proxiДл&quot;: proxy})
    # Дальше ваша логика...</pre>
  <h3 id="3IjE">Теперь главный враг автоматизации CAPTCHA</h3>
  <blockquote id="Gl6m"><em>CAPTCHA можно проходить самыми разными способами от солвером до обучения локальных ИИ-моделей</em></blockquote>
  <figure id="iVzH" class="m_original">
    <img src="https://img3.teletype.in/files/a1/8f/a18f63fb-34f4-4190-8108-80aa66a9d61f.png" width="560" />
  </figure>
  <p id="Eu6N"><strong>Интеграция с сервисом решения:</strong></p>
  <pre id="F9mf" data-lang="python">import requests
import time

API_KEY = &quot;your_2captcha_key&quot;

def solve_recaptcha(site_key, page_url):
    # Отправляем задачу
    response = requests.post(&quot;https://api.2captcha.com/in.php&quot;, data={
        &quot;key&quot;: API_KEY,
        &quot;method&quot;: &quot;userrecaptcha&quot;,
        &quot;googlekey&quot;: site_key,
        &quot;pageurl&quot;: page_url,
        &quot;json&quot;: 1
    })
    task_id = response.json()[&quot;request&quot;]
    
    # Ждём решение
    for _ in range(30):
        time.sleep(5)
        result = requests.get(&quot;https://api.2captcha.com/res.php&quot;, params={
            &quot;key&quot;: API_KEY,
            &quot;action&quot;: &quot;get&quot;,
            &quot;id&quot;: task_id,
            &quot;json&quot;: 1
        })
        if result.json()[&quot;status&quot;] == 1:
            return result.json()[&quot;request&quot;]
    
    return None</pre>
  <h2 id="7qzo">Часть 4: Инфраструктура</h2>
  <h3 id="7ul7">Прокси — виды и стратегии</h3>
  <p id="jMAn">1. HTTP прокси → обычные, для http запросов<br />2. SOCKS5 прокси → любой трафик<br />3. Резидентные → IP реальных людей (дорого, надёжно)<br />4. Датацентровые → IP серверов (дёшево, палевно)<br />5. Мобильные → IP мобильных операторов (самые надёжные)<br />6. Ротация → новый IP на каждый запрос<br />7. Стик → IP привязан к сессии</p>
  <p id="4H8t"><strong>Правильная ротация:</strong></p>
  <pre id="ylJz" data-lang="python">import aiohttp
import asyncio
from itertools import cycle

class ProxyPool:
    def __init__(self, proxy_list):
        self.proxies = cycle(proxy_list)
        self.failed = set()
    
    def get_proxy(self):
        for _ in range(len(self.proxies)):
            proxy = next(self.proxies)
            if proxy not in self.failed:
                return proxy
        # Все прокси умерли — сбрасываем
        self.failed.clear()
        return next(self.proxies)
    
    def mark_failed(self, proxy):
        self.failed.add(proxy)

async def fetch(session, url, proxy):
    try:
        async with session.get(url, proxy=proxy, timeout=10) as resp:
            return await resp.json()
    except:
        pool.mark_failed(proxy)
        return None

async def main(urls):
    pool = ProxyPool([
        &quot;http://proxy1:8080&quot;,
        &quot;http://proxy2:8080&quot;,
    ])
    
    connector = aiohttp.TCPConnector(limit=20)
    async with aiohttp.ClientSession(connector=connector) as session:
        tasks = []
        for url in urls:
            proxy = pool.get_proxy()
            tasks.append(fetch(session, url, proxy))
        
        results = await asyncio.gather(*tasks)
    return [r for r in results if r is not None]</pre>
  <h2 id="Pt2p">Часть 5: Практические схемы</h2>
  <h3 id="wCHs">Схема 1: Сбор данных с каталога</h3>
  <pre id="vBbj" data-lang="python">from playwright.sync_api import sync_playwright
from bs4 import BeautifulSoup
import json
import time
import random

class CatalogParser:
    def __init__(self, base_url):
        self.base_url = base_url
        self.results = []
    
    def parse_page(self, page, url):
        page.goto(url)
        page.wait_for_load_state(&quot;networkidle&quot;)
        
        # Ждём появления товаров
        page.wait_for_selector(&quot;.product-card&quot;, timeout=10000)
        
        html = page.content()
        soup = BeautifulSoup(html, &quot;html.parser&quot;)
        
        products = soup.select(&quot;.product-card&quot;)
        
        for product in products:
            self.results.append({
                &quot;title&quot;: product.select_one(&quot;.title&quot;)?.text.strip(),
                &quot;price&quot;: product.select_one(&quot;.price&quot;)?.text.strip(),
                &quot;url&quot;: product.select_one(&quot;a&quot;)?.get(&quot;href&quot;),
                &quot;parsed_at&quot;: time.strftime(&quot;%Y-%m-%d %H:%M&quot;)
            })
        
        # Случайная задержка
        time.sleep(random.uniform(2, 5))
    
    def run(self, pages=10):
        with sync_playwright() as p:
            browser = p.chromium.launch(headless=True)
            page = browser.new_page()
            
            for i in range(1, pages + 1):
                url = f&quot;{self.base_url}?page={i}&quot;
                print(f&quot;Страница {i}/{pages}&quot;)
                self.parse_page(page, url)
            
            browser.close()
        
        return self.results
    
    def save(self, filename=&quot;data.json&quot;):
        with open(filename, &quot;w&quot;, encoding=&quot;utf-8&quot;) as f:
            json.dump(self.results, f, ensure_ascii=False, indent=2)

# Использование
parser = CatalogParser(&quot;https://example.com/catalog&quot;)
data = parser.run(pages=50)
parser.save()</pre>
  <h3 id="KwuT"><br />Схема 2: Мониторинг изменений</h3>
  <pre id="JUvg" data-lang="python">import hashlib
import json
from datetime import datetime
from pathlib import Path

class ChangeMonitor:
    def __init__(self, state_file=&quot;state.json&quot;):
        self.state_file = Path(state_file)
        self.state = self.load_state()
    
    def load_state(self):
        if self.state_file.exists():
            return json.loads(self.state_file.read_text())
        return {}
    
    def save_state(self):
        self.state_file.write_text(
            json.dumps(self.state, ensure_ascii=False, indent=2)
        )
    
    def get_hash(self, data):
        return hashlib.md5(json.dumps(data, sort_keys=True).encode()).hexdigest()
    
    def check(self, key, new_data):
        new_hash = self.get_hash(new_data)
        old_hash = self.state.get(key, {}).get(&quot;hash&quot;)
        
        if old_hash is None:
            self.state[key] = {&quot;hash&quot;: new_hash, &quot;data&quot;: new_data, &quot;updated&quot;: datetime.now().isoformat()}
            return {&quot;status&quot;: &quot;new&quot;, &quot;data&quot;: new_data}
        
        elif old_hash != new_hash:
            old = self.state[key][&quot;data&quot;]
            self.state[key] = {&quot;hash&quot;: new_hash, &quot;data&quot;: new_data, &quot;updated&quot;: datetime.now().isoformat()}
            return {&quot;status&quot;: &quot;changed&quot;, &quot;old&quot;: old, &quot;new&quot;: new_data}
        
        return {&quot;status&quot;: &quot;unchanged&quot;}</pre>
  <p id="kKWH"></p>
  <h3 id="Ox4c">Схема 3: Распределённый парсер</h3>
  <pre id="7RC2" data-lang="python">import asyncio
import aiohttp
from dataclasses import dataclass, field
from typing import Optional
import json

@dataclass
class Task:
    url: str
    retries: int = 0
    max_retries: int = 3
    proxy: Optional[str] = None

@dataclass
class Worker:
    id: int
    session: aiohttp.ClientSession
    queue: asyncio.Queue
    results: list = field(default_factory=list)

class DistributedParser:
    def __init__(self, urls, num_workers=5, proxy_list=None):
        self.tasks = [Task(url=url) for url in urls]
        self.num_workers = num_workers
        self.proxy_list = proxy_list or []
        self.results = []
    
    async def worker(self, wid, queue, session):
        while True:
            try:
                task = await asyncio.wait_for(queue.get(), timeout=5)
            except asyncio.TimeoutError:
                break
            
            try:
                proxy = None
                if self.proxy_list:
                    proxy = self.proxy_list[task.retries % len(self.proxy_list)]
                
                async with session.get(
                    task.url, 
                    proxy=proxy,
                    timeout=aiohttp.ClientTimeout(total=15)
                ) as resp:
                    if resp.status == 200:
                        data = await resp.text()
                        self.results.append({
                            &quot;url&quot;: task.url,
                            &quot;data&quot;: data,
                            &quot;worker&quot;: wid
                        })
                        print(f&quot;[Worker {wid}] OK: {task.url}&quot;)
                    else:
                        raise Exception(f&quot;Status {resp.status}&quot;)
                        
            except Exception as e:
                task.retries += 1
                if task.retries &lt; task.max_retries:
                    await queue.put(task)
                else:
                    print(f&quot;[Worker {wid}] FAILED: {task.url} - {e}&quot;)
            
            finally:
                queue.task_done()
    
    async def run(self):
        queue = asyncio.Queue()
        for task in self.tasks:
            queue.put(task)
        
        connector = aiohttp.TCPConnector(limit=self.num_workers * 2)
        
        async with aiohttp.ClientSession(connector=connector) as session:
            workers = [
                asyncio.create_task(self.worker(i, queue, session))
                for i in range(self.num_workers)
            ]
            await queue.join()
            for w in workers:
                w.cancel()
        
        return self.results

# Использование
urls = [f&quot;https://example.com/item/{i}&quot; for i in range(1000)]
parser = DistributedParser(
    urls=urls, 
    num_workers=10,
    proxy_list=[&quot;http://p1:8080&quot;, &quot;http://p2:8080&quot;, &quot;http://p3:8080&quot;]
)
results = asyncio.run(parser.run())</pre>
  <p id="ocw4"></p>
  <h2 id="TLlR">Часть 6: Стек инструментов</h2>
  <h3 id="GVK4">Обязательный минимум</h3>
  <ul id="h0lH">
    <li id="lRso">requests — базовые HTTP запросы</li>
    <li id="TFKA">httpx — async HTTP, HTTP/2</li>
    <li id="bU0M">beautifulsoup4 — парсинг HTML</li>
    <li id="0Ioc">lxml — быстрый парсер</li>
    <li id="6gg4">playwright — headless браузер</li>
    <li id="Nx7q">scrapy — фреймворк для масштабных проектов</li>
  </ul>
  <h3 id="sjxN">Стань лучше:</h3>
  <ul id="a3A4">
    <li id="sXnk">curl_cffi — имитация TLS fingerprint браузера</li>
    <li id="YMnl">tls_client — обход Cloudflare через TLS</li>
    <li id="uGab">camoufox — анти-детект Firefox</li>
    <li id="noed">undetected-chromedriver — анти-детект Chrome</li>
    <li id="d8dJ">aiohttp — async для скорости</li>
    <li id="Ou9y">celery — очереди задач</li>
    <li id="I0JW">redis — кэш и состояние</li>
    <li id="gL8X">postgresql — хранилище данных</li>
    <li id="49kW">docker — изоляция окружения (на уровне базовый минимум)</li>
  </ul>
  <h3 id="ObOv">Инфраструктура (Может не подойти)</h3>
  <p id="YdrV">Прокси-провайдеры:</p>
  <ul id="dXNG">
    <li id="0moO">Bright Data (резидентные)</li>
    <li id="6xwK">SmartProxy (резидентные)</li>
    <li id="ghsl">Proxy-Seller (датацентровые)</li>
    <li id="tC7c">IPRoyal (мобильные)</li>
  </ul>
  <p id="2c5N">Решение капчи:</p>
  <ul id="CHP5">
    <li id="cVeA">2Captcha</li>
    <li id="laYk">Anti-Captcha</li>
    <li id="aEB2">CapSolver</li>
  </ul>
  <p id="plNt">Мониторинг:</p>
  <ul id="To3q">
    <li id="9NZM">Grafana + Prometheus</li>
    <li id="y1ji">Telegram-бот алерты</li>
  </ul>
  <h2 id="l4Hw">Часть 7: Как НЕ надо</h2>
  <ul id="Qhwq">
    <li id="wPeJ">ДДОСить сайт парсером (1000 req/sec)</li>
    <li id="H4ih">Игнорировать ошибки и повторять бесконечно</li>
    <li id="rtx2">Хранить данные без структуры</li>
    <li id="8lxb">Не логировать — не понимаешь что происходит</li>
    <li id="ZLtW">Хардкодить селекторы без фоллбеков</li>
    <li id="M66j">Не обрабатывать изменение вёрстк</li>
    <li id="F0HI">Собирать всё подряд без цели</li>
    <li id="rZ9Y">Не кэшировать — один и тот же запрос 50 раз</li>
    <li id="NCWG">Писать всё в один файл без модульности</li>
    <li id="X0Ml">Игнорировать robots.txt и уважение к серверу</li>
  </ul>
  <p id="ZfAs"></p>
  <p id="kx2b"></p>
  <blockquote id="QOtz"><em>На этом все с вами был Vatican.</em></blockquote>

]]></content:encoded></item></channel></rss>