<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <language>ru</language>
    <title>Парсинг</title>
    <description/>
    <link>https://tproger.ru/tag/parsing</link>
    <atom:link href="https://tproger.ru/tag/parsing/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Sat, 03 Oct 2026 21:21:12 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>Парсинг</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>RAG-бот для любого сайта на Python за 60 строк кода</title>
      <link>https://tproger.ru/articles/rag-bot-dlya-lyubogo-sajta-na-python-za-60-strok-koda</link>
      <comments>https://tproger.ru/articles/rag-bot-dlya-lyubogo-sajta-na-python-za-60-strok-koda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/rag-bot-dlya-lyubogo-sajta-na-python-za-60-strok-koda</guid>
      <description><![CDATA[<p>Соберите простого RAG-бота на Python, который читает любую веб-страницу и отвечает на вопросы только по её тексту. Гайд с кодом и объяснениями.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/rag-bot-dlya-lyubogo-sajta-na-python-za-60-strok-koda">RAG-бот для любого сайта на Python за 60 строк кода</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Обучение программированию]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 26 Aug 2026 12:06:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если попросить языковую модель ответить по свежей документации или конкретному сайту, она с блеском выдумает то, чего там нет. Стандартное решение — <strong>Retrieval-Augmented Generation (RAG)</strong>: сначала достать реальный текст, найти в нём нужные куски и только потом передать их модели в качестве контекста.</p><p>В этой статье соберём работающего RAG-бота, который отвечает на вопросы о любой веб-странице, примерно на 60 строках Python. Никаких парсеров HTML, headless-браузеров и сложных фреймворков — только requests, локальная Ollama и чистый Markdown.</p><h2>Что такое RAG</h2><p>RAG (retrieval-augmented generation) — это подход, при котором языковая модель не отвечает по своей памяти, а сначала ищет релевантные фрагменты во внешнем тексте, а потом генерирует ответ на их основе. Это резко снижает галлюцинации и позволяет работать с данными, которых не было в обучающей выборке.</p><ul><li>RAG-бот на Python укладывается в ~60 строк и работает без облачных LLM.</li><li>Самое неприятное в RAG-пайплайне — очистка HTML; готовый Markdown API убирает эту работу.</li><li>Текст разбивается на чанки (~1200 символов), каждый превращается в эмбеддинг и сравнивается с эмбеддингом вопроса.</li><li>Локальные модели nomic-embed-text и llama3 через Ollama не требуют иностранных карт и VPN.</li><li>Качество ответа зависит от качества исходного текста: сырой HTML зашумляет поиск, чистый Markdown улучшает ретривл.</li></ul><h2>Что мы соберём</h2><p>Архитектура бота простая и универсальная:</p><ol><li>Отправляем URL в сервис извлечения текста и получаем чистый Markdown.</li><li>Разбиваем Markdown на фрагменты (чанки) по границам абзацев.</li><li>Превращаем каждый чанк в вектор — эмбеддинг.</li><li>То же самое делаем с вопросом пользователя.</li><li>Находим чанки, ближайшие к вопросу, по косинусной близости.</li><li>Отдаём найденные фрагменты + вопрос языковой модели с инструкцией отвечать только по контексту.</li></ol><p>Такая схема легко масштабируется: можно заменить локальную Ollama на OpenAI, Anthropic или российские модели, а векторы перенести в Qdrant или Chroma.</p><h2>Что понадобится</h2><ul><li>Python 3.9+</li><li>Библиотека requests</li><li>Локально запущенная Ollama с моделями nomic-embed-text и llama3</li><li>Доступ к API извлечения текста (в примере — <a href="https://rapidapi.com/xiaobao882026/api/web-to-markdown-json-api" rel="noopener noreferrer">Web to Markdown/JSON API</a>; бесплатный тариф даёт 50 запросов в сутки)</li></ul><h2>Код бота</h2><p>Сохраните скрипт как rag_bot.py и подставьте свой ключ, если сервис извлечения текста требует авторизации:</p><p><b>На что обратить внимание:</b><br />Если вы используете RapidAPI-версию сервиса, запрос к API_URL обычно требует заголовка X-RapidAPI-Key. Без ключа бесплатный endpoint может вернуть 401.</p><h3>Разбор по частям</h3><p>fetch_markdown — единственный внешний вызов. Сервис сам забирает страницу, убирает навигацию, баннеры и футер и возвращает Markdown: заголовки, абзацы, списки. Это освобождает от зависимостей вроде BeautifulSoup или headless Chrome.</p><p>chunk_markdown режет текст на фрагменты примерно по 1200 символов, не разрывая абзацы. Мелкие чанки дают более точный ретривл, но увеличивают число эмбеддингов; для начала 1200 символов — хороший баланс.</p><p>embed и cosine превращают текст в векторы и считают их близость. Модель nomic-embed-text из Ollama бесплатна, быстрая и неплохо понимает русский и английский.</p><p>answer эмбеддит вопрос, выбирает три самых похожих чанка и строит промпт с жёстким ограничением: отвечать только по контексту. Это главная страховка от галлюцинаций.</p><h2>Запуск</h2><p>Установите зависимости и скачайте модели в Ollama:</p><p>Если всё в порядке, в консоли появится примерно такой результат:</p><h2>Почему важен чистый Markdown</h2><p>Если скормить эмбеддинг-модели сырой HTML, в векторах окажутся теги &lt;div&gt;, меню навигации и копирайты из футера. В результате поиск похожести выдаст «Copyright © 2026» вместо полезного ответа. Чистый Markdown — заголовки, абзацы, списки — улучшает качество ретривла почти бесплатно.</p><p>Если не хочется зависеть от внешнего API, можно заменить fetch_markdown на один из альтернативных вариантов:</p><ul><li><a href="https://github.com/adbar/trafilatura" rel="noopener noreferrer">trafilatura</a> — библиотека на Python для извлечения главного текста.</li><li><a href="https://r.jina.ai/http://example.com" rel="noopener noreferrer">r.jina.ai/http://URL</a> — бесплатный сервис без ключа.</li><li><a href="https://www.firecrawl.dev/" rel="noopener noreferrer">Firecrawl</a> — API с поддержкой сканирования сайтов целиком.</li><li><a href="https://github.com/scrapingbee" rel="noopener noreferrer">ScrapingBee</a> — прокси + рендеринг для сложных страниц.</li></ul><p>Для российских разработчиков локальная Ollama особенно удобна: модели качаются бесплатно, не нужны иностранные карты, а инференс идёт на своём железе.</p><h2>Куда развивать</h2><ul><li>Направьте бота на документацию, чейнджлог или блог конкурента и задавайте вопросы по ним.</li><li>Замените Ollama на OpenAI, Anthropic, Gemini или российские модели — функция answer меняется в двух строках.</li><li>Сохраняйте эмбеддинги в векторную БД: Chroma, Qdrant или FAISS, чтобы индексировать сразу много страниц.</li><li>Используйте формат json вместо Markdown, если нужна структура: параграфы, заголовки, ссылки — отдельно.</li></ul><h2>Выводы</h2><p>RAG — не магия, а последовательность простых шагов: получить чистый текст, разрезать его на фрагменты, найти ближайшие к вопросу и отдать их модели. Весь минимальный пайплайн укладывается в короткий Python-скрипт, который можно запустить на своём ноутбуке.</p><blockquote>RAG работает ровно так хорошо, каков текст, который вы ему скармливаете. Уберите самую утомительную часть — очистку HTML, — и останется интересное: поиск и генерация.</blockquote><p>Исходник идеи — статья <a href="https://dev.to/bao001_xiao_37db0a18ce6b2/chat-with-any-website-build-a-rag-bot-in-60-lines-of-python-1m1k" rel="noopener noreferrer">«Chat With Any Website: Build a RAG Bot in ~60 Lines of Python»</a>. Попробуйте собрать бота на своей странице и посмотрите, где он справляется, а где начинает фантазировать.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как Android-инженер спроектировал gateway для миллионов пользователей: опыт перехода в инфраструктуру</title>
      <link>https://tproger.ru/articles/kak-android-inzhener-sproektiroval-gateway-dlya-millionov-polzova</link>
      <comments>https://tproger.ru/articles/kak-android-inzhener-sproektiroval-gateway-dlya-millionov-polzova?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Кирилл Соколов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-android-inzhener-sproektiroval-gateway-dlya-millionov-polzova</guid>
      <description><![CDATA[<p>История перехода из андроид разработки в инфраструктуру. Как мобильный инженер спроектировал gateway для платформы с миллионами пользователей, освоил распределённые системы и научился строить отказоустойчивые сервисы.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-android-inzhener-sproektiroval-gateway-dlya-millionov-polzova">Как Android-инженер спроектировал gateway для миллионов пользователей: опыт перехода в инфраструктуру</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[App Store]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 23 Jun 2026 07:41:54 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Перешёл из Android-разработки в инфраструктуру и спроектировал gateway для платформы с миллионами пользователей. Делюсь опытом: какие пробелы пришлось закрывать, почему мобильный бэкграунд — это преимущество, и с чего начать, если думаете о похожем переходе. </i></p><h2>Почему инфраструктура начинает привлекать больше, чем фичи</h2><p>С фичами всё прозрачно: написал код — увидел результат на экране. Быстрая и понятная обратная связь. Но со временем замечаешь, что проблемы повторяются. Приложение тормозит не из-за плохого кода, а потому что на один экран уходит пять-шесть сетевых вызовов. Логика на клиенте. Хочешь что-то изменить — готовь релиз, проходи App Store Review и жди недели, пока обновление дойдёт до всех.</p><p>Я перешёл в Android-инфраструктуру — начал делать инструменты для других мобильных разработчиков. Это помогло увидеть: главные проблемы не в фичах, а в слое между приложением и бэкендом.</p><p>Возвращаться к фичам стало неинтересно. В инфраструктуре задачи сложнее, результат измеряется метриками — latency, error rate, скорость релизов, — а влияние на всю систему, а не на один экран.</p><h2>Что Android даёт для инфраструктуры — а чему учиться с нуля</h2><p>Мобильный бэкграунд оказался не балластом, а преимуществом. Я понимал ограничения изнутри. Backend-инженер может прочитать, что мобильные сети ненадёжны, память ограничена, а батарея — критичный ресурс. Но прочитать и прочувствовать — разное. Я годами наблюдал, как приложение “захлёбывается” на устройствах среднего сегмента. Знал, что 60% пользователей сидят именно на таких. Видел, как баг, который мы починили за день, продолжает висеть у людей неделями — просто потому, что они не успели обновиться.</p><p>Когда я проектировал gateway, я точно знал, что почувствуют мобильные разработчики, если ошибусь. Добавить ещё один сетевой вызов — это будет не бесплатно. Оставить логику в приложении — значит отдать её на устройство, которое я не контролирую.</p><p><b>Чего именно не хватало?</b> Я неплохо понимал мобильную сторону, но совершенно не ориентировался в распределенных системах. Знал, например, что такое таймаут, но не представлял, как выставить его в цепочке из пяти сервисов так, чтобы одно медленное звено не обрушило весь экран пользователя. Понимал, что сети падают, но не умел проектировать систему, способную оставаться на плаву в таких условиях.</p><p><b>Чему пришлось учиться с нуля? </b>Операционному мышлению. В Android ты выпускаешь релиз — и он либо работает, либо нет. Если крашится, починишь в следующей версии. В инфраструктуре нет «следующей версии». Если gateway падает, всё приложение ложится для миллионов пользователей прямо сейчас.</p><p>Пришлось учиться думать в терминах деградации, частичных отказов, плавного падения.</p><p>Что делать, если один из пяти сервисов не ответил? Как понять, что мы катимся к инциденту, до того, как пользователи начнут жаловаться?</p><p>Этому в мобильной разработке не учат.</p><h2>Как я учился: пробелы, сроки и смена мышления</h2><p>Формального плана у меня не было — учился на практике. Это лучший, хотя и самый стрессовый способ. Пробелы выявляла практика. Столкнулся с нерешаемой задачей — понял, чего не знаю. Пошёл разбираться.</p><p>Учился итеративно, не пытаясь объять необъятное сразу. Gateway начинался как простой прокси. Затем добавили агрегацию ответов, потом — конфигурационные определения экранов. Каждый такой шаг вынуждал осваивать следующий уровень: circuit breakers, стратегии повторов, observability, планирование мощностей.</p><p>По срокам: техническая база уложилась в несколько месяцев. Паттерны осваиваются быстрее, чем кажется, особенно если сразу применять их к живой задаче. Гораздо дольше происходила смена образа мышления. Перейти от вопроса «работает ли фича?» к вопросу «что случится, когда это упадёт в три часа ночи?» — вот что заняло основное время.</p><h2>Что означает «выдающийся уровень» в инфраструктуре</h2><p><i>Когда говорят «спроектировать gateway с нуля и перевести на него живую платформу», за этими словами стоит не один навык, а целых три, и каждый требует совершенно разной подготовки.</i></p><p>Проектирование с нуля — это не рисование квадратиков на доске и не выбор модного стека. Это в первую очередь определение границ: что система будет делать, а что — категорически нет, и как с ней станут взаимодействовать десятки команд. Настоящая сложность здесь в том, чтобы предвидеть, что именно сломается, и заложить защиту от этого ещё до того, как написан хоть один файл с кодом.</p><p>Затем — миграция живой системы, где права на ошибку практически нет. Приложение нельзя выключить или отрепетировать в реальном масштабе. Остаётся только постепенный перевод трафика: shadow mode → 1% → 5% → 25% → 50% → 100%, с автоматическим откатом при любом росте ошибок. И всё это — пока миллионы пользователей активно работают с продуктом, не подозревая, что под капотом идёт замена двигателя на ходу. Такой уровень дисциплины и инструментации приходит только с практикой.</p><p>Наконец, владение надёжностью. Gateway — единая точка отказа: упал он, упало всё. Годы уходят на то, чтобы сделать его скучным и предсказуемым: резервирование, автомасштабирование, circuit breakers, режимы деградации, еженедельный пересмотр мощностей. Высший пилотаж — когда о системе просто не думаешь, потому что она работает.</p><h2>Почему путь в инфраструктуру доступнее, чем кажется?</h2><p>Карьерные траектории в инфраструктуре редко бывают чётко описаны. Здесь нет готового чек-листа в духе «диплом по Computer Science, пять лет в бэкенде, обязательное знание Kafka и Kubernetes». С одной стороны, такая неопределённость пугает. С другой — именно она и делает этот путь более доступным, чем принято думать.</p><p>Когда перед тобой лежит жёсткий список формальных требований, люди часто отсеивают себя сами, даже не попробовав. А в инфраструктуре по-настоящему важно только одно: можешь ли ты решать задачи. Я пришёл сюда без профильного диплома и учился ровно тому, что требовалось в моменте, потому что задачи сами подталкивали к этому.</p><p>Индустрия, к слову, до сих пор не слишком хорошо умеет проверять те навыки, которые на этом уровне оказываются решающими: умение видеть ограничения на стыке систем, предвидеть сценарии отказов, двигать людей к соглашению. Всему этому учатся не до начала работы, а непосредственно в процессе.</p><p>Поэтому если вы мобильный инженер и размышляете, можно ли перейти в инфраструктуру, — вопрос не в том, правильный ли у вас бэкграунд. Вопрос в другом: готовы ли вы учиться тому, чего пока не знаете, и способны ли обратить то, что уже понимаете, в собственное преимущество. Если ответ «да» — путь для вас открыт. Просто указателей на нём пока не расставили.</p><h2>Мобильный бэкграунд как преимущество архитектора</h2><p>Считаю ли я, что мобильный опыт сделал меня лучшим архитектором для mobile-first продуктов? Безоговорочно, да.</p><p>Я помнил, как ощущается медленный экран на устройстве среднего сегмента. Помнил, что случается, когда API возвращает слегка неправильные данные и приложение падает при парсинге. Помнил то чувство, когда баг уже в проде, а ты ждёшь App Store Review и ничего не можешь исправить.</p><p>Поэтому когда я проектировал gateway, я не занимался абстрактной «оптимизацией перформанса». Я опирался на совершенно конкретный опыт. Знал, что убрать один сетевой round trip — это подарок каждому мобильному разработчику. Знал, что перенос логики на сервер означает перенос в место, где я могу починить всё за минуты, а не за недели.</p><p>Лучшая инфраструктура для мобильных продуктов строится теми, кто сам их создавал и знает все узкие места не понаслышке. Этот опыт даёт верное направление: ты чувствуешь, где настоящие проблемы, потому что сталкивался с ними лично. Такому не учат по книгам.</p><h2>Коротко: что делать, если думаете о переходе</h2><ul><li>Найдите промежуточный шаг. Не прыгайте сразу в бэкенд. Начните с задач на стыке: оптимизация API, инструменты для мобильных разработчиков, улучшение сетевого слоя.</li><li>Используйте мобильный контекст как рычаг. Вы понимаете то, о чём бэкенд-инженеры только догадываются. Говорите об этом вслух.</li><li>Учитесь измерять невидимое. В инфраструктуре результат — это метрики: latency, error rate, скорость релизов. Учитесь рассказывать историю через цифры.</li><li>Проектируйте под отказ, а не тушите пожары. Senior-уровень — это определить, что сломается и кто за это отвечает, до того, как оно сломается.</li><li>Не ждите разрешения. Путь не размечен, но он открыт. Начните с малого — и двигайтесь туда, где задачи становятся интереснее.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Как Саймон Уиллисон перенёс LiteParse в браузер за 59 минут — перевод</title>
      <link>https://tproger.ru/translations/kak-sajmon-uillison-perenyos-liteparse-v-brauzer-za-59-minut-pe</link>
      <comments>https://tproger.ru/translations/kak-sajmon-uillison-perenyos-liteparse-v-brauzer-za-59-minut-pe?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/kak-sajmon-uillison-perenyos-liteparse-v-brauzer-za-59-minut-pe</guid>
      <description><![CDATA[<p>Саймон Уиллисон за 59 минут с Claude Code перенёс LiteParse из Node.js CLI в браузер: PDF.js и Tesseract.js, приватно и без сервера. Перевод с разбором.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/kak-sajmon-uillison-perenyos-liteparse-v-brauzer-za-59-minut-pe">Как Саймон Уиллисон перенёс LiteParse в браузер за 59 минут — перевод</a>»</p>]]></description>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 24 Apr 2026 12:30:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>59 минут с Claude Code и Opus 4.7 — и опенсорсный PDF-парсер LlamaIndex заработал прямо в браузере. Саймон Уиллисон перенёс <a href="https://simonw.github.io/liteparse/" rel="nofollow">LiteParse</a> из Node.js CLI в чистый браузерный JS: PDF.js и Tesseract.js делают весь парсинг локально, файл никуда не уходит.</p><p>Ниже — перевод <a href="https://simonwillison.net/2026/Apr/23/liteparse-for-the-web/" rel="nofollow">статьи Уиллисона</a>: что такое LiteParse, почему его удалось перенести в браузер и как выглядит вайб-кодинг, когда автор не читает ни строчки из получившегося HTML и TypeScript.</p><p><b>LiteParse от LlamaIndex</b> — классический PDF-парсинг без ИИ. Эвристики spatial text parsing вычисляют порядок чтения (колонки, подписи, сноски), а Tesseract OCR добирает сканы.</p><p><b>Браузерная версия</b> собрана из тех же PDF.js и Tesseract.js — никакого сервера, данные остаются на устройстве.</p><p><b>Процесс</b>: план в plan.md, команда «build it», очередь follow-up-промтов, Playwright + red/green TDD, деплой на GitHub Pages через Actions.</p><p><b>Время</b> в Claude Code на фазу сборки — 59 минут. Уиллисон не прочитал ни одной строки получившегося кода.</p><p><b>Уиллисон готов привязать к проекту репутацию</b> — редкий случай для его вайб-проектов. Статический сайт и полная приватность делают blast radius почти нулевым.</p><h2>Что такое LiteParse и зачем он нужен</h2><p>LlamaIndex выложили опенсорс-инструмент <a href="https://github.com/run-llama/liteparse" rel="nofollow">LiteParse</a> — Node.js CLI для извлечения текста из PDF. Что приятно: LiteParse не использует ИИ-модели. Это старый добрый PDF-парсинг с фолбеком на Tesseract OCR (или другой подключаемый OCR-движок) для файлов, где «текст» представлен картинками страниц, а не самим текстом.</p><p>Сложная задача, которую решает LiteParse, — выдать текст в нормальном порядке, несмотря на причудливые макеты PDF. Авторы называют это «spatial text parsing», пространственным парсингом: хитрые эвристики распознают многоколоночную вёрстку и группируют блоки так, чтобы текст читался линейно.</p><p>В документации LiteParse описан паттерн <a href="https://developers.llamaindex.ai/liteparse/guides/visual-citations/" rel="nofollow">Visual Citations with Bounding Boxes</a> — «визуальные цитаты с ограничивающими рамками». Уиллисону идея нравится: отвечать на вопросы по PDF и прикладывать к ответу обрезанный и подсвеченный фрагмент исходника — хороший способ поднять доверие к ответам RAG-системы (retrieval-augmented generation — когда LLM отвечает, подтягивая нужные куски из базы документов).</p><p>LiteParse задуман как CLI для агентов. Запускается вот так:</p><p>Уиллисон попробовал инструмент с Claude и быстро понял: оставаться CLI-приложением LiteParse вовсе не обязан. Он построен на PDF.js и Tesseract.js — двух библиотеках, с которыми автор уже <a href="https://simonwillison.net/2024/Mar/30/ocr-pdfs-images/" rel="nofollow">делал похожие штуки в браузере</a>. Единственная причина, почему у LiteParse до сих пор не было чистой браузерной версии, — её просто никто не сделал.</p><h2>Знакомство: LiteParse в браузере</h2><p>Зайдите на <a href="https://simonw.github.io/liteparse/" rel="nofollow">simonw.github.io/liteparse/</a> и попробуйте инструмент на любом PDF — всё работает прямо в вашем браузере. Интерфейс минимальный: перетаскиваете файл, выбираете режим (с OCR или без), на выходе получаете распознанный текст и pretty-printed JSON, оба с кнопкой Copy. Опционально можно вывести превью всех страниц PDF.</p><h2>Как это собрали с Claude Code и Opus 4.7</h2><p>Всё началось в обычном приложении Claude на iPhone. Уиллисон хотел пощупать LiteParse и загрузил с телефона случайный PDF с таким промтом:</p><blockquote>Clone https://github.com/run-llama/liteparse and try it against this file</blockquote><p>Обычный Claude теперь умеет клонировать репозитории прямо с GitHub и ставить пакеты из PyPI и npm — даже без доступа к остальному интернету из контейнера. Уиллисон часто так пробует новый опенсорс с телефона, не доставая ноутбук. После нескольких уточняющих вопросов (весь диалог можно <a href="https://claude.ai/share/44a5ed86-e5b5-4e14-90be-1eba1e0acd13" rel="nofollow">открыть в расшаренном транскрипте</a>) он спросил главное:</p><blockquote>Does this library run in a browser? Could it?</blockquote><p>Ответ был достаточно убедительным, чтобы попробовать всерьёз. Уиллисон открыл ноутбук, переключился на Claude Code. Форкнул оригинальный репозиторий на GitHub, склонировал локальную копию, создал новую ветку web и скопировал последний ответ Claude в файл <a href="https://github.com/simonw/liteparse/blob/web/notes.md" rel="nofollow">notes.md</a>. А потом сказал Claude Code:</p><blockquote>Get this working as a web app. index.html, when loaded, should render an app that lets users open a PDF in their browser and select OCR or non-OCR mode and have this run. Read notes.md for initial research on this problem, then write out plan.md with your detailed implementation plan</blockquote><p>Подобные проекты Уиллисон всегда начинает с плана. Иногда он включает у Claude «режим планирования», но здесь ему нужен был план как артефакт в репозитории — поэтому сразу plan.md. Это позволяет итеративно править сам план. Заметив, что Claude решил отложить «canvas-encode swap» (замену способа, которым PDF.js сохраняет страницы картинкой — без неё не работает превью страниц в браузерной версии) на v2, Уиллисон дописал:</p><blockquote>Update the plan to say we WILL do the canvas-encode swap so the screenshots thing works</blockquote><p>Через несколько коротких правок получился <a href="https://github.com/simonw/liteparse/blob/web/plan.md" rel="nofollow">plan.md</a>, который автор счёл достаточно хорошим для реализации. И сказал:</p><blockquote>build it.</blockquote><p>И дальше Уиллисон по большей части оставил Claude Code работать самому: возился с другими проектами, периодически заглядывал проверить прогресс. Параллельно подбрасывал подсказки в очередь. Queued-prompts не попадают в стандартный экспорт транскрипта Claude Code, но их можно вытащить из папки ~/.claude/projects/ командой rg queue-operation --no-filename | grep enqueue | jq -r '.content'. Ниже — выдержка из этих follow-up-промтов с авторскими комментариями:</p><ul><li>«Реализуй через Playwright и red/green TDD, спланируй это тоже» — подробнее про red/green TDD Уиллисон <a href="https://simonwillison.net/guides/agentic-engineering-patterns/red-green-tdd/" rel="nofollow">писал отдельно</a></li><li>«Давай использовать собственный рендерер PDF.js» — Claude начал экспериментировать с pdfium</li><li>«Финальный UI должен показывать и текст, и pretty-printed JSON — оба в textarea с кнопками копирования. И должен быть mobile-friendly» — новая идея, как UI должен выглядеть</li><li>«Делай маленькие коммиты по ходу дела» — <i>см. ниже</i></li><li>«В index.html вверху страницы добавь ссылку на <a href="https://github.com/run-llama/liteparse" rel="nofollow">github.com/run-llama/liteparse</a>» — важно кредитить зависимости</li><li>«View on GitHub → — плохая формулировка: это репозиторий не браузерной обёртки, а базовой библиотеки LiteParse»</li><li>«Чекбокс Run OCR должен быть снят по умолчанию»</li><li>«Когда пытаюсь распарсить PDF в браузере — вижу Parse failed: undefined is not a function» — Claude тестировал в Playwright под Chrome, а оказалось, что это баг Safari</li><li>«Когда нажимают Copy, пусть текст на 1,5 секунды меняется на Copied!»</li><li>«Оформи поле выбора файла так, чтобы длинные имена не ломали вёрстку в Firefox. И добавь drag-and-drop-зону, которая ещё и кликабельна» — скриншоты мелких UI-глитчей Claude воспринимает на удивление хорошо</li><li>«Текст в drop-зоне сейчас чуть ближе к верху — поцентруй по вертикали» — точечная правка поверх предыдущей</li><li>«В Safari на macOS всё ещё падает с readableStream» — Claude починил, как только ему подсказали запустить Playwright в этом браузере; следующим промтом Уиллисон подтвердил: «works in safari now»</li></ul><p>«Делай маленькие коммиты» Уиллисон теперь просит по привычке: это упрощает последующее чтение и ревью кода, а ещё, по его непроверенной гипотезе, помогает агенту работать эффективнее — дополнительный стимул планировать и брать задачи по одной.</p><p>Пока агент работал, Уиллисон решил, что было бы неплохо уже повзаимодействовать с ещё не завершённой версией. Он открыл отдельную сессию Claude Code в той же папке и спросил, как запустить сборку. Ответ — npx vite: команда поднимает dev-сервер с live-reload, так что каждая правка на диске сразу видна в браузере, и можно тут же просить «подкрути вот это».</p><p>Ближе к концу Уиллисон решил, что проект достаточно хорош для публикации. Новая сессия Claude Code, промт:</p><blockquote>Look at the web/ folder - set up GitHub actions for this repo such that any push runs the tests, and if the tests pass it then does a GitHub Pages deploy of the built vite app such that the web/index.html page is the index.html page for the thing that is deployed and it works on GitHub Pages</blockquote><p>После нескольких итераций получился <a href="https://github.com/simonw/liteparse/blob/web/.github/workflows/deploy-web.yml" rel="nofollow">рабочий GitHub Actions workflow</a>, который собирает приложение через Vite и деплоит результат на <a href="https://simonw.github.io/liteparse/" rel="nofollow">simonw.github.io/liteparse/</a>. GitHub Pages Уиллисон любит именно за такие кейсы: любой репозиторий бесплатно превращается в задеплоенное веб-приложение с произвольным build-шагом — и всё это настраивает Claude.</p><p>В проектах такого типа всегда есть риск, что модель «сжульничает»: пометит ключевые фичи как TODO и сделает их заглушками или срежет углы в требованиях. Ответственный способ это поймать — прочитать весь код. Но здесь это не планировалось, поэтому Уиллисон запустил OpenAI Codex с GPT-5.5 (у автора был ранний доступ к модели) и попросил:</p><blockquote>Describe the difference between how the node.js CLI tool runs and how the web/ version runs</blockquote><p>Ответ был достаточно подробным, чтобы убедиться: Claude не срезал углы в чём-то критичном. Суммарное время в Claude Code на фазу «build it» — <b>59 минут</b>. Полный транскрипт сессии Уиллисон потом экспортировал своим же инструментом <a href="https://github.com/simonw/claude-code-transcripts" rel="nofollow">claude-code-transcripts</a> — правда, без очереди follow-up-промтов, их экспорт пока не подхватывает.</p><h2>Это ещё вайб-кодинг или уже нет?</h2><p>Уиллисон педантичен в определении <a href="https://simonwillison.net/2025/Mar/19/vibe-coding/" rel="nofollow">vibe coding</a>: это не любое использование ИИ для написания кода. Вайб-кодинг — это когда вы используете ИИ и при этом вообще не просматриваете получившийся код и не думаете о нём. По собственному определению автора, LiteParse for the web — пожалуй, максимально чистый вайб-кодинг: ни одной строки HTML и TypeScript Уиллисон не прочитал (и, пока писал это предложение, даже полез проверять, JS там или TS).</p><p>И всё же этот проект не ощущается как другие его вайб-проекты:</p><ul><li>Это статическое браузерное приложение на GitHub Pages. Blast radius (радиус поражения от бага) почти нулевой: для конкретного PDF оно или работает, или нет.</li><li>Приватные данные никуда не уходят — вся обработка в браузере, поэтому аудит безопасности не нужен. Уиллисон специально заглянул в network-панель и убедился: при парсинге PDF дополнительных запросов нет.</li><li>Инженерный опыт всё равно потребовался — чтобы сообразить, что перенос LiteParse в браузер вообще возможен. Без этого никакой агент не справился бы.</li></ul><p>Главное — Уиллисон готов привязать к этому проекту свою репутацию и рекомендовать его другим. В отличие от большинства его вайб-проектов, он не уверен, что дополнительные инженерные часы заметно улучшили бы первый релиз. «Оно работает как есть, и это нормально».</p><p>PR в апстрим Уиллисон не открывал — не обсуждал это с командой LiteParse. Но <a href="https://github.com/run-llama/liteparse/issues/147" rel="nofollow">завёл issue</a>: если команде будет интересно взять вайб-код как отправную точку для чего-то более официального — пусть забирают.</p><h2>Выводы</h2><p>LiteParse for the web — не прорыв, а аккуратная обёртка поверх PDF.js и Tesseract.js. Но с конкретной пользой: приватный парсинг PDF без облака, который можно забрать и поставить у себя.</p><p>Главное в кейсе — не сама браузерная обёртка, а рабочий паттерн: план-артефакт в репозитории, запуск через «build it», очередь follow-up-подсказок поверх работающего агента и финальная проверка результата другой моделью. Такой процесс повторяется на любом проекте сопоставимой сложности.</p><p>Оригинал: <a href="https://simonwillison.net/2026/Apr/23/liteparse-for-the-web/" rel="nofollow">Extract PDF text in your browser with LiteParse for the web</a> Simon Willison, 23 апреля 2026 года. Апстрим-репозиторий LiteParse — <a href="https://github.com/run-llama/liteparse" rel="nofollow">github.com/run-llama/liteparse</a>, демо браузерной версии — <a href="https://simonw.github.io/liteparse/" rel="nofollow">simonw.github.io/liteparse/</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Интуиция за Pratt parsing: как работают приоритеты операторов</title>
      <link>https://tproger.ru/translations/intuiciya-za-pratt-parsing--kak-rabotayut-prioritety-operatorov</link>
      <comments>https://tproger.ru/translations/intuiciya-za-pratt-parsing--kak-rabotayut-prioritety-operatorov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/intuiciya-za-pratt-parsing--kak-rabotayut-prioritety-operatorov</guid>
      <description><![CDATA[<p>Понятное объяснение алгоритма Pratt parsing: как деревья разбора наклоняются по приоритету операторов, что такое binding power (LBP/RBP) и как написать корректный парсер за 10 строк на Python.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/intuiciya-za-pratt-parsing--kak-rabotayut-prioritety-operatorov">Интуиция за Pratt parsing: как работают приоритеты операторов</a>»</p>]]></description>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Компиляторы]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 30 Mar 2026 15:10:50 GMT</pubDate>
      <content:encoded><![CDATA[<p>Перевод статьи <a href="https://louis.co.nz/2026/03/26/pratt-parsing.html">Intuiting Pratt parsing</a>. Автор: Louis.</p><p>Вы знаете, что a + b * c + d вычисляется как a + (b * c) + d. Но как объяснить это машине? Как закодировать правила приоритета операторов так точно, чтобы парсер сам правильно строил дерево разбора?</p><p>Pratt parsing — элегантный алгоритм, придуманный Воном Праттом в 1973 году. Он лежит в основе парсеров многих современных языков, но его описания часто сводятся к магическим таблицам приоритетов без объяснения, почему это работает. Эта статья строит интуицию с нуля.</p><p>— AST — основная структура данных: оператор над операндами, вычисление снизу вверх.</p><p>— Приоритет операторов определяет наклон дерева: выше приоритет — глубже в дерево.</p><p>— При падении приоритета алгоритм поднимается по «хребту» дерева — это и есть суть Pratt parsing.</p><p>— Левая и правая ассоциативность задаются через LBP и RBP (left/right binding power).</p><p>— Полный парсер с поддержкой всех операторов — около 10 строк на Python.</p><h2>Абстрактное синтаксическое дерево</h2><p>Наиболее распространённое решение для разбора выражений — абстрактное синтаксическое дерево (AST, Abstract Syntax Tree). В AST каждый оператор стоит над своими операндами. Вычисление идёт снизу вверх: сначала обрабатываются дочерние узлы, затем операция над ними.</p><p>Для выражения a + b * c + d правильное AST выглядит так:</p><p>Узел * находится глубже, чем +, — это и отражает более высокий приоритет умножения. При вычислении сначала перемножаются b * c, результат складывается с a, затем прибавляется d.</p><h2>Как приоритет влияет на форму дерева</h2><p>Здесь кроется главная интуиция Pratt parsing. Приоритет операторов напрямую определяет, в какую сторону «наклоняется» дерево:</p><ul><li><b>Убывающий приоритет</b> (например, * + ==) — дерево наклонено влево: операторы с большим приоритетом оказываются глубже.</li><li><b>Возрастающий приоритет</b> (например, == + *) — дерево наклонено вправо.</li><li><b>Равный приоритет</b> — по соглашению левая ассоциативность, дерево наклоняется влево.</li></ul><p>Рассмотрим промежуточное состояние разбора. Пусть мы уже построили дерево I для выражения (a &gt; b + c * d) — это правонаклонное дерево: &gt; наверху, * в самом низу.</p><p>Теперь встречаем следующий оператор. Куда вставить новый узел? Зависит от приоритета:</p><ul><li><b>[I] * e</b> — приоритет * не меньше приоритета * в дереве, вставляем в самый глубокий узел.</li><li><b>[I] + e</b> — приоритет + ниже *, но выше &gt;, поднимаемся по хребту выше узла *.</li><li><b>[I] == e</b> — приоритет == ниже всего дерева, всё дерево I становится левым потомком.</li></ul><p><b>Ключевое наблюдение:</b> когда встречается оператор с меньшим приоритетом, мы поднимаемся по правому хребту дерева, собирая узлы с более высоким приоритетом. Это и есть Pratt parsing — алгоритм, который реализует именно этот подъём по хребту.</p><h2>От интуиции к коду</h2><p>Начнём с простого случая — правонаклонного дерева. Каждый оператор правоассоциативен, приоритет не учитывается:</p><p>Здесь leaf() читает следующий терминал (число или переменную), peek() смотрит на текущий токен без продвижения, advance() читает и сдвигает позицию.</p><p>Добавляем приоритет. Рекурсивный вызов передаёт приоритет текущего оператора как порог — это ограничивает, какие операторы следующий уровень может «захватить»:</p><p>Это уже работает для правоассоциативных операторов. Но у нас if — разобрали один оператор и вышли. Для левоассоциативных нужен цикл:</p><h3>Полный Pratt parser</h3><p>Замена if на while — это и есть процедура подъёма по хребту дерева. Цикл продолжается, пока следующий оператор имеет достаточно высокий приоритет, чтобы «захватить» левую часть. Как только приоритет падает — выходим, и текущее поддерево передаётся вверх по стеку вызовов.</p><h3>Правая ассоциативность через binding power</h3><p>До сих пор у нас одно число приоритета на оператор. Но для управления ассоциативностью нужно различать, насколько «сильно» оператор притягивает операнды слева и справа. Вводятся два понятия:</p><ul><li><b>LBP (left binding power)</b> — сила притяжения левого операнда.</li><li><b>RBP (right binding power)</b> — сила притяжения правого операнда.</li></ul><p>Правила ассоциативности через binding power:</p><ul><li><b>Левоассоциативные операторы</b> (+, *): LBP == RBP. Правый рекурсивный вызов получает тот же приоритет — следующий оператор с таким же приоритетом не захватывается, строится левое дерево.</li><li><b>Правоассоциативные операторы</b> (**, =): RBP = LBP − 1. Правый рекурсивный вызов получает чуть меньший приоритет — следующий оператор с таким же приоритетом захватывается, строится правое дерево.</li></ul><p>Это финальная версия Pratt parser. Всего 8 строк кода — и корректный разбор всех операторов с любым приоритетом и ассоциативностью.</p><h2>Итог</h2><p>Pratt parsing — не хитрый трюк, а следствие простой геометрической интуиции. Деревья разбора наклоняются влево или вправо в зависимости от приоритета операторов. Когда встречается оператор с меньшим приоритетом, алгоритм поднимается по правому хребту текущего дерева — ровно настолько, насколько нужно.</p><p>Ключевые детали реализации:</p><ul><li>while вместо if — реализует подъём по хребту для левоассоциативных операторов.</li><li>Передача приоритета в рекурсию — ограничивает, какие операторы «захватываются» на следующем уровне.</li><li>LBP / RBP — контролируют ассоциативность через разницу в единицу.</li></ul><p>Понимание этой геометрии делает Pratt parsing прозрачным: каждая строка кода отражает конкретное геометрическое действие с деревом, а не магию таблиц приоритетов.</p>]]></content:encoded>
    </item>
    <item>
      <title>5 опенсорс-инструментов для повседневной работы разработчика</title>
      <link>https://tproger.ru/articles/5-opensors-instrumentov-dlya-povsednevnoj-raboty-razrabotchika</link>
      <comments>https://tproger.ru/articles/5-opensors-instrumentov-dlya-povsednevnoj-raboty-razrabotchika?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Валерия Турчак]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/5-opensors-instrumentov-dlya-povsednevnoj-raboty-razrabotchika</guid>
      <description><![CDATA[<p>Для работы с видео, паролями, серверами, торрентами и защиты экрана от любопытных глаз.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/5-opensors-instrumentov-dlya-povsednevnoj-raboty-razrabotchika">5 опенсорс-инструментов для повседневной работы разработчика</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[macOS]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[YouTube]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Видеоконтент]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 11 Dec 2025 12:50:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Рабочий день программиста состоит не только из написания кода. Нужно управлять серверами, скачивать видео для обучения, хранить секреты проектов, работать с торрент-архивами документации и защищать конфиденциальные данные на экране. Для каждой из этих задач есть готовые решения, но часто они либо платные, либо требуют облачной подписки, либо закрыты.</p><p>Мы собрали пять свободных инструментов, которые решают типичные задачи разработчика: от скачивания видео с любых сайтов до защиты от подглядывающих коллег. Все они работают локально или self-hosted, не отправляют данные в облако и распространяются с открытым исходным кодом.</p><p>Больше подобных находок — в тг-канале <a href="https://t.me/+P6xe2tVbQWU2NDhi">Инструменты программиста</a>. Там каждый день появляются свежие CLI-утилиты, GUI-приложения, библиотеки и сервисы для разработки. Всё протестировано, с примерами использования и ссылками на репозитории.</p><h2>GUI для скачивания видео: yt-channel-downloader</h2><p><a href="https://github.com/hyperfield/yt-channel-downloader/">yt-channel-downloader</a> — графическое приложение для скачивания видео с YouTube и любых других сайтов, где есть видеоконтент. Это не только видеохостинги: если на странице есть видео, приложение попытается его скачать.</p><p>Под капотом работает связка из трёх Python-библиотек: yt-dlp для универсального парсинга, scrapetube для работы с каналами и плейлистами, pytube как вспомогательный инструмент. Поверх этого — кроссплатформенный графический интерфейс для Windows, macOS и Linux.</p><p>Как это работает: вводите ссылку на видео, плейлист или целый канал. Приложение подтягивает список доступных роликов и даёт выбрать, что именно качать — целиком или выборочно. Можно скачать только аудиодорожку или выбрать конкретное качество видео.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-12-11/638e1ddb-0815-4e1a-8919-178e91ef38d5.jpeg" alt="" /></figure><p>Полезные особенности:</p><ul><li>Вход в аккаунт YouTube прямо из приложения. Это позволяет скачивать приватные ролики, доступные только по ссылке или для авторизованных пользователей. Куки хранятся в локальном конфиге и автоматически очищаются при выходе из аккаунта.</li><li>Пометка уже скачанных файлов. Не нужно вручную проверять, что уже есть на диске.</li><li>Ограничение параллельных потоков. Если качаете большой плейлист, можно задать лимит одновременных загрузок, чтобы очередь не подвисала и не перегружала канал.</li></ul><p>Для работы нужен установленный ffmpeg — он используется для конвертации и склейки потоков. Для пользователей Windows доступен <a href="https://github.com/hyperfield/yt-channel-downloader/releases">готовый инсталлятор в разделе Releases</a> (размещён на SourceForge).</p><p>Код и инструкции по установке — <a href="https://github.com/hyperfield/yt-channel-downloader/">на GitHub</a>. В планах у автора: поддержка скачивания YouTube Shorts, поиск по полученному списку видео, более наглядный прогресс-бар, история загрузок и расширенная поддержка других видеоплощадок.</p><h2>gopass — менеджер паролей для разработчиков</h2><p><a href="https://github.com/gopasspw/gopass">gopass</a> — консольный менеджер паролей, заточенный под командную работу и версионирование. Все секреты хранятся в виде файлов, шифруются через GPG и версионируются в Git. Вы можете держать их локально, синхронизировать через любой git-ремоут (GitHub, GitLab, собственный сервер) и при этом всегда иметь историю изменений.</p><p>Рабочий цикл выглядит консольно и привычно для разработчиков. Из терминала вы листаете хранилище командой gopass ls, смотрите конкретный пароль через gopass show, генерируете новый — gopass generate. Копирование в буфер обмена тоже работает из командной строки, что удобно для скриптов и автоматизации.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-12-11/a7518a77-b4b1-47a5-8b0f-1e4bcb19061c.jpeg" alt="" /></figure><p>Поверх базовой функциональности есть плагины:</p><ul><li>gopass-bridge — интеграция с браузером. Позволяет автоматически заполнять формы входа без копирования паролей вручную.</li><li>Помощь с Git-кредами. gopass может выступать credential helper для Git, так что пароли от репозиториев тоже хранятся зашифрованными и версионируются.</li><li>Проверка через Have I Been Pwned. Можно проверить, не утекли ли ваши пароли в публичные базы.</li></ul><p>GPG обеспечивает асимметричное шифрование: секреты зашифрованы вашим публичным ключом, приватная часть не покидает машину. Если работаете в команде, достаточно добавить GPG-ключи коллег в хранилище — каждый сможет расшифровать общие секреты своим приватным ключом. При этом никто не видит приватных ключей других участников.</p><p>gopass написан на Go, поэтому работает на macOS, Linux и Windows без дополнительных зависимостей. Настройка сводится к созданию git-репозитория с зашифрованными файлами и клонированию его на рабочие машины. Один репозиторий — доступ с любого устройства.</p><p><a href="https://github.com/gopasspw/gopass">Код в репозитории</a>, документация подробная, есть примеры для всех основных сценариев использования.</p><h2>Self-hosted SSH-клиент: Termix</h2><p><a href="https://github.com/Termix-SSH/Termix">Termix</a> — полностью опенсорсная и self-hosted альтернатива Termius для управления серверами по SSH через единый веб-интерфейс. Разворачивается в Docker как бэкенд, синхронизируется с клиентами под веб, Windows, Linux, macOS, iOS и Android.</p><p>Ключевые возможности:</p><ul><li>SSH-терминал с вкладками и сплитами. Можно открыть до 4 панелей одновременно, переключаться между сессиями, кастомизировать тему оформления и шрифты. Всё работает через браузер или нативное приложение.</li><li>SSH-туннели с автопереподключением. Настраиваете туннель один раз, система сама восстанавливает соединение при обрывах и отслеживает состояние туннелей в реальном времени.</li><li>Файловый менеджер поверх SSH. Можно просматривать и редактировать код прямо в интерфейсе, смотреть картинки, слушать аудио, проигрывать видео, загружать и выгружать файлы, выполнять операции копирования, перемещения, удаления — всё без отдельного SFTP-клиента.</li><li>Менеджер хостов. Организация серверов по тегам и папкам, автоматическая заливка SSH-ключей на хосты, безопасное хранение логинов и паролей в зашифрованной базе.</li><li>Мониторинг. Для любого подключённого сервера можно посмотреть загрузку CPU, память, диск, сеть, аптайм и системную информацию. Есть дашборд с общим обзором по всем хостам.</li></ul><p>Под капотом: веб-клиент собран на React + Tailwind + Shadcn, бэкенд работает с зашифрованной базой SQLite, автоматическая настройка SSL-сертификатов, вход через OIDC и двухфакторная аутентификация (TOTP). Интерфейс поддерживает несколько языков.</p><p>Проект распространяется под Apache 2.0. Основной способ установки — docker-compose с томом для данных, всё настраивается за пару минут. Для десктопа и мобильных устройств доступны нативные сборки и приложения в официальных сторах под все основные платформы.</p><p><a href="https://github.com/Termix-SSH/Termix">Код в репозитории</a>, на скриншотах видно, как выглядит интерфейс — аккуратно, функционально, без лишних элементов.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-12-11/ae32f5b2-ef82-4e08-9018-270c5eaccfa6.jpg" alt="" /></figure><h2>TUI-клиент для торрентов: Torrra v2</h2><p><a href="https://github.com/stabldev/torrra">Torrra</a> — TUI-клиент для поиска и скачивания торрентов прямо из консоли, без браузера и без отдельного GUI-приложения. Написан на Python, интерфейс собран на библиотеке Textual, так что всё выглядит аккуратно и отзывчиво даже в терминале.</p><p>Можно подключаться к своим индексаторам Jackett или Prowlarr, смотреть результаты поиска и выбирать, чем качать. Есть два режима: через встроенный движок на базе libtorrent или передать magnet-ссылку во внешний торрент-клиент (Transmission, qBittorrent и так далее).</p><p>Автор утверждает, что во второй версии серьёзно ускорил UI, улучшил навигацию по спискам, прокачал поиск и добавил возможность работы с несколькими торрентами одновременно. Плюс почистил интеграцию с индексаторами и отполировал раскладку интерфейса — теперь всё помещается в стандартное окно терминала без скроллинга.</p><p>Установить можно несколькими способами:</p><ul><li>Через pipx: pipx install torrra</li><li>Из AUR для пользователей Arch Linux</li><li>Через Homebrew на macOS</li><li>Docker-образ для изолированного запуска</li><li>Готовые бинарники под Linux, macOS и Windows</li></ul><p>После установки минимальный сценарий работы такой: поднимаете Jackett или Prowlarr (это отдельные сервисы для агрегации торрент-индексаторов), запускаете</p><p>Дальше стрелками ходите по списку результатов, Enter — начать скачивание, p — пауза, r — продолжить, q — выйти из программы.</p><p>Поведение можно подкрутить через файл config.toml: задать дефолтные индексаторы, пути для сохранения файлов, какие клиенты использовать для загрузки, чтобы каждый раз не вбивать одно и то же в аргументах командной строки.</p><p>Проект кроссплатформенный (Linux/macOS/Windows) и активно развивается: есть подробная документация, регулярные релизы, автор отвечает на issues. <a href="https://github.com/stabldev/torrra">Код в репозитории</a>, на видео можно посмотреть демонстрацию работы.</p><h2>Защита от подглядывания: EyesOff для macOS</h2><p><a href="https://github.com/YM2132/EyesOff">EyesOff</a> — приложение для macOS, которое следит через веб-камеру и предупреждает, когда кто-то подглядывает в ваш экран. Актуально для работы в опенспейсах, коворкингах или просто дома, когда не хочется, чтобы кто-то читал ваш код или переписку через плечо.</p><p>Написано на Python + PyQt, модель распознавания лиц крутится локально на вашем Mac — ничего не уходит в облако, никакие кадры не сохраняются. Есть три режима оповещения на выбор:</p><ul><li>Попап на экране — появляется окно с предупреждением, что кто-то смотрит.</li><li>Системная нотификация — более деликатный вариант, уведомление в углу экрана.</li><li>Автозапуск приложения — можно настроить, чтобы автоматически запускалась блокировка экрана или любое другое приложение.</li></ul><p>Автор написал <a href="https://ym2132.github.io/building_EyesOff_part2_model_training">подробный разбор</a> того, как тренировал модель детекции. Интересный момент: он оптимизировал accuracy не в среднем по всем дистанциям, а конкретно для mid-range (~1-2 метра) — именно там обычно стоят любопытные коллеги. На близких дистанциях (менее метра) и дальних (более трёх метров) точность может быть ниже, но это компромисс ради производительности и практичности.</p><p>Есть одно ограничение: приложение пока детектит просто наличие лиц в кадре, а не направление взгляда. То есть если человек в кадре, но смотрит в сторону или на свой телефон, EyesOff всё равно сработает. Автор обещает доработать определение направления взгляда в следующих версиях, но для большинства сценариев текущей логики достаточно.</p><p>Для параноиков и тех, кто работает с конфиденциальными данными в публичных местах, это полезный инструмент. Код открыт, можно посмотреть, как именно работает детекция, и убедиться, что никакие данные не утекают.</p><p>Все пять инструментов объединяет один принцип: контроль над своими данными. Вы не зависите от подписок, облачных сервисов или закрытых платформ. Каждый из них решает конкретную задачу, делает это хорошо и не требует доверять кому-то свои пароли, SSH-ключи или видео с камеры. Код открыт, можно проверить, как всё устроено, и при желании — доработать под свои нужды.</p>]]></content:encoded>
    </item>
    <item>
      <title>Куда двигаться после изучения Django: советы для Python-разработчиков</title>
      <link>https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299</link>
      <comments>https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгения Епихина]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299</guid>
      <description><![CDATA[<p>В статье разбираемся, почему Django — далеко не финиш в карьере, и в каких направлениях можно двигаться Python-разработчику.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299">Куда двигаться после изучения Django: советы для Python-разработчиков</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Raspberry Pi]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Асинхронное программирование]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[NoSQL]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Neo4j]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 12 Aug 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Django — это веб-фреймворк на языке Python, который позволяет быстро создавать сложные веб-приложения. Он включает в себя готовые компоненты для работы с базами данных, маршрутизацией URL, обработкой форм, аутентификацией пользователей и админ-панелями, что значительно ускоряет разработку и упрощает поддержку проектов.</p><p>Владение Django — это старт, а не финиш. Чтобы оставаться востребованным, нужно постоянно расширять знания и навыки. В этой статье разберем пути и направления для улучшения своих компетенций.</p><h2>Почему владение Django — не предел для разработчика</h2><h2>Особенности Django</h2><p>Django используют для разработки веб-приложений разной сложности: при работе с большими базами данных, для создания сервисов, способных обслуживать большое количество пользователей. На нём создают соцсети, новостные сайты, веб-версии приложений, онлайн-магазины.</p><p>Основные плюсы:</p><ul><li><b>Полноценный стек</b>: ORM для работы с базой, мощная система маршрутизации URL, шаблоны для рендеринга, встроенная админка, формы, система аутентификации и авторизации.</li><li><b>Архитектура MTV (Model-Template-View)</b>: похожа на классический MVC, но с особенностями, которые упрощают разделение логики, представления и данных.</li><li><b>Безопасность</b>: Django автоматически защищает от CSRF, XSS, SQL-инъекций и других распространенных атак. Не нужно писать много дополнительного кода.</li><li><b>Активное сообщество и экосистема</b>: тысячи сторонних пакетов, расширений и готовых решений.</li><li><b>Поддержка нескольких баз данны</b>х: PostgreSQL, MySQL, SQLite, Oracle и др.</li></ul><p>Ограничения:</p><ul><li><b>Синхронная природа Django</b>.</li><li><b>Монолитность</b>: архитектура фреймворка ориентирована на создание крупных приложений, но в микросервисах может быть избыточна.</li><li><b>Ограниченная гибкость ORM</b>: нестандартные SQL-запросы иногда сложно выразить средствами ORM, приходится использовать raw SQL или сторонние библиотеки для запросов.</li><li><b>Строгие правила организации кода</b>: требуют дисциплины и могут ограничивать свободу в архитектурных решениях.</li><li><b>Недостаточная производительность</b>: уступает лёгким асинхронным фреймворкам (например, FastAPI), особенно под высокими нагрузками. Но для большинства проектов пока это не критично.</li></ul><h2>В каком направлении двигаться после изучения Django</h2><blockquote>Задача — создавать продукт, который будет нужен конечному потребителю.</blockquote><h3>Первое направление для развития — расширить инструментарий для решения разных задач в веб-разработке</h3><p>Возможные пути:</p><ul><li>Изучить другие веб-фреймворки (Flask, FastAPI)</li><li>Углубиться в асинхронное программирование (asyncio, aiohttp)</li><li>Работать с API и микросервисами</li></ul><h4>Flask и FastAPI</h4><p>Flask — минималистичный микрофреймворк, даёт полную свободу в выборе компонентов. Используют для небольших приложений и микросервисов.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-12/bbe7c040-14de-426d-9a10-c556f7319bee.png" alt="" /><figcaption>Пример простой команды на Flask</figcaption></figure><p>FastAPI — современный асинхронный фреймворк, ориентирован на создание высокопроизводительных API. Поддерживает стандарт OpenAPI и автоматическую генерацию документации. Он быстрее Flask и Django благодаря asyncio и Pydantic.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-12/33a27277-5136-4a03-8af2-f436db42fa99.png" alt="" /><figcaption>Пример простого API на FastAPI</figcaption></figure><h4>Асинхронное программирование</h4><p>Веб-разработка всё активнее использует асинхронные технологии. Django не всегда справляется с задачами высокой конкурентной нагрузки.</p><p>Поэтому изучение asyncio — стандартной библиотеки Python для асинхронного программирования — откроет перед вами новые возможности. Вместе с aiohttp или тем же FastAPI вы сможете создавать приложения, которые обрабатывают тысячи одновременных соединений. Это особенно важно для real-time сервисов, чат-приложений и систем с интенсивным обменом данными.</p><h3>Второе направление — расширить навыки в смежных областях</h3><p>Можно пойти по пути расширения компетенций за пределы основной специализации. Важно не только уметь писать код, но и понимать, как приложения разворачиваются и работают в продакшене. Знание DevOps-практик помогает наладить эффективное взаимодействие между разработкой и эксплуатацией.</p><h4>Изучение DevOps и контейнеризации</h4><p>Контейнеры позволяют запускать приложения в изолированной среде, это упрощает настройку и развертывание. Например, Docker помогает упаковать приложение с зависимостями в один контейнер, а Kubernetes — управлять такими контейнерами в продакшене. Знание этих технологий улучшит взаимодействие с операционной командой и ускорит выпуск новых версий приложений.</p><h4>CI/CD и автоматизация процессов</h4><p>Непрерывная интеграция (Continuous Integration) и непрерывное развертывание (Continuous Deployment) — ключевые практики современной разработки ПО. Они позволяют автоматизировать сборку, тестирование и доставку приложений, масштабировать процессы.</p><p>Инструменты CI/CD (например, Jenkins, GitLab CI/CD, GitHub Actions) помогают настроить автоматические пайплайны, которые обеспечивают быструю обратную связь и минимизируют человеческий фактор в релизах. Автоматизация процессов снижает количество ошибок и позволяет сосредоточиться на разработке новых функций.</p><p>Настройка непрерывной интеграции и доставки (Continuous Integration / Continuous Delivery) снижает поток ошибок при релизах и экономит время. Пример: GitHub Actions для автоматического запуска тестов и сборки проекта при каждом коммите.</p><h4>Больше знаний в области баз данных</h4><p>Помимо классических реляционных баз данных (PostgreSQL, MySQL), современные приложения часто используют NoSQL для специфичных задач. MongoDB, Redis, Cassandra обеспечивают гибкость в хранении данных, горизонтальное масштабирование и высокую производительность при работе с большими объемами информации.</p><p>Графовые базы данных (Neo4j, ArangoDB) предназначены для эффективного хранения и анализа связей между объектами, что важно для социальных сетей, рекомендательных систем и других приложений с богатой структурой.</p><p>Так, Redis хорошо подходит для кэширования данных, а Neo4j — для сложных связей между объектами.</p><h3>Третье направление — переход к другим аспектам Python-разработки</h3><p>Рассмотрим четыре варианта карьерного развития для Python-программиста: Data Science и машинное обучение, автоматизация бизнес-процессов, разработка десктопных приложений и встраиваемые системы (IoT).</p><p>Почему стоит попробовать?</p><ul><li>Высокий спрос на специалистов. Они востребованы в банках и инвестиционных компаниях, в сфере медицины и биотехнологии, в консалтинге,  автомобильной промышленности и т.д..</li><li>Широкий набор библиотек: pandas, NumPy, scikit-learn, TensorFlow, PyTorch.</li><li>Возможность работать с реальными задачами: от бизнеса до науки.</li></ul><h4>Автоматизация и скрипты для бизнеса</h4><p>Python часто используется для автоматизации рутинных задач: парсинга данных, обработки файлов, интеграции систем, генерации отчетов. Создание скриптов для автоматизации бизнес-процессов помогает повысить эффективность работы и снизить количество ошибок.</p><p>Знание таких библиотек, как openpyxl (работа с Excel), requests (HTTP-запросы), BeautifulSoup и Scrapy (парсинг веб-страниц), а также умение писать скрипты под конкретные задачи, делают разработчика ценным специалистом в корпоративной среде.</p><p>Примеры задач:</p><ul><li>Автоматическая загрузка данных из Excel и их преобразование</li><li>Скрипты для отправки email-рассылок</li><li>Интеграция с CRM и другими сервисами через API</li></ul><h4>Разработка десктопных приложений (PyQt, Kivy)</h4><p>Хотя сейчас популярность уходит к вебу и мобильным платформам, десктопные приложения на Python востребованы в таких сферах: инструменты для анализа, редакторы, утилиты.</p><p>Инструменты для создания:</p><ul><li>PyQt — мощный фреймворк для создания кроссплатформенных GUI.</li><li>Kivy — библиотека для разработки приложений с поддержкой сенсорных экранов.</li></ul><p>Этот путь подходит тем, кто хочет создавать удобные инструменты с графическим интерфейсом для пользователей на Windows, macOS или Linux.</p><h4>Встраиваемые системы и IoT</h4><p>В области IoT и встроенных систем Python набирает популярность благодаря легкости освоения и поддержке на маломощных устройствах. Помогают в этом  платформы по типу Raspberry Pi и MicroPython.</p><p>Изучение этого направления открывает возможности работы с аппаратным обеспечением, созданием прототипов и внедрением инновационных решений в промышленности и бытовой технике.</p><p>Например, с помощью Python на Raspberry Pi можно  разрабатывать датчики для мониторинга состояния оборудования на производстве и разрабатывать прототипы носимых устройств для сбора данных о здоровье.</p><blockquote>Если рассматривать профессию “Python-разработчик на Django”, то сразу получится сужение до конкретной библиотеки на конкретном языке. Если же в резюме у специалиста стоит, что он “разработчик Python”, возможностей сильно больше. Если написать про себя “разработчик”, будет не понятно, разработчик чего. Но изменив резюме на “DevOps инженера”, становится понятен карьерный трек.</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>10 библиотек Python, которые меняют карьеру</title>
      <link>https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru</link>
      <comments>https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru</guid>
      <description><![CDATA[<p>10 библиотек Python, которые помогут прокачаться в аналитике, ML и разработке. Как они работают и почему меняют карьеру.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru">10 библиотек Python, которые меняют карьеру</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Jupyter Notebook]]></category>
      <category><![CDATA[Визуализация]]></category>
      <category><![CDATA[Образование]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Анализ данных]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 17 Jul 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>У Python тысячи библиотек, но лишь немногие действительно меняют карьеру. Они помогают не просто решать задачи, а ускорять проекты, прокачивать навыки и выходить на следующий уровень в аналитике, машинном обучении и разработке. В этом материале мы собрали 10 библиотек, которые помогут зарабатывать на Python и развивать навыки.</p><h2>1. Pandas</h2><p>Pandas — библиотека для работы с данными в Python, позволяющая легко загружать, анализировать, очищать и преобразовывать числовую информацию в удобной табличной форме. По сути, это Excel, который смог, и позволяет делать всё автоматизировано и на порядки быстрее.</p><p>Библиотека строится вокруг двух ключевых структур: <b>Series</b> (одномерный массив с индексами); <b>DataFrame </b>(таблица с индексами и колонками).</p><h3>Какие задачи решает библиотека</h3><p>Pandas полезна для следующих задач:</p><ul><li>Сам анализ данных: можно быстро фильтровать, группировать, агрегировать и строить сводные таблицы.</li><li>Очистка данных: удаляем пустые строки, заменяем значения, приводим типы.</li><li>Загрузка данных из CSV, Excel, SQL.</li><li>Визуальная разведка данных (EDA) перед построением моделей.</li><li>Подготовка данных для ML и отчётов.</li><li>Автоматизация отчётов и ETL-пайплайнов.</li></ul><p>Благодаря Pandas аналитик превращается в инженера данных, а ML-специалист может сосредоточиться на моделях, а не на ручной подготовке датасетов.</p><h3>Как пользоваться</h3><p>Ниже разберём простейший кейс: нужно загрузить данные о зарплатах разработчиков из CSV, посчитать среднюю зарплату по языкам программирования и отобрать топ-5.</p><h3>Почему это меняет карьеру</h3><p>Работа с Pandas становится границей между знанием Python и умением решать задачи бизнеса. Для <b>джуна </b>это шанс сразу показать практическую пользу: выгрузки, отчёты и базовый анализ можно делать в десятки раз быстрее и аккуратнее, чем вручную в эксельке.</p><p>Для <b>аналитика</b> Pandas превращается в главный рабочий инструмент, позволяя не просто проверять гипотезы и делать сводные таблицы, а строить полноценные отчётные пайплайны, автоматизировать рутинные выгрузки и концентрироваться на сути данных, а не на правках ручками.</p><p>Для <b>ML-инженера</b> владеть Pandas — значит уметь готовить датасеты качественно; быстро очищать и приводить данные к нужному виду, что напрямую влияет на результат моделей. Без этого работа над проектами машинного обучения часто превращается в бесконечную возню с данными.</p><p>Наконец, даже для <b>разработчиков</b> Pandas может стать неожиданным бустом в карьере. Например, когда нужно автоматизировать отчёты для бизнеса или быстро анализировать логи и данные из БД без поднятия дашбордов — Pandas даёт гибкость и скорость, которые редко даёт что-то ещё в экосистеме Python.</p><h2>2. Django</h2><p>Django — фреймворк для веб-разработки на Python, который позволяет быстро создавать надежные и масштабируемые веб-приложения. Он следует принципам DRY (Don’t Repeat Yourself — не повторяй себя), предоставляя разработчику ORM, роутинг, систему авторизации, админку, работу с формами, шаблонами и инструментами безопасности из коробки.</p><p>Django подходит как стартапам, которым нужно быстро выйти на рынок, так и крупным проектам с миллионами пользователей. Это не просто библиотека, а полноценный каркас для построения и сопровождения веб-сервисов.</p><h3>Какие задачи решает библиотека</h3><p>Каркас, действительно, каркасный. Задачи следующие:</p><ul><li>Создание веб-приложений и API любой сложности.</li><li>Быстрая разработка MVP, прототипов и коммерческих проектов.</li><li>Упрощение работы с базами данных через ORM, без написания сырого SQL.</li><li>Построение административных панелей для управления данными без ручной разработки.</li><li>Гибкая маршрутизация и работа с формами, валидацией и шаблонами.</li><li>Реализация аутентификации, авторизации и защиты приложений.</li></ul><p>Django позволяет сосредоточиться на бизнес-логике и продукте, не тратить недели на настройку инфраструктуры.</p><h3>Как пользоваться</h3><p>Устанавливаем:</p><p>Создаем проект и приложение:</p><p>Пример модели:</p><p>Миграция базы данных:</p><p>Создание админки:</p><p>После этого можно запустить сервер:</p><p>И перейти по адресу http://127.0.0.1:8000/admin для управления записями через готовую админ-панель.</p><h2>3. PyTorch</h2><p>PyTorch — мощная библиотека Python. Она позволяет строить и обучать нейронные сети, проводить вычисления с автоматическим дифференцированием и работать с GPU для ускорения самих вычислений.</p><p>Главное отличие PyTorch от других ML-фреймворков — динамическая вычислительная графика (define-by-run): модель строится и изменяется во время выполнения кода, что даёт гибкость при создании и отладке сложных моделей.</p><p>Сегодня PyTorch используется в продакшен системах, научных исследованиях, компьютерном зрении, NLP и генеративных моделях, занимая ведущее место в индустрии.</p><h3>Какие задачи решает библиотека</h3><p>В функционал PyTorch входят:</p><ul><li>Построение нейронных сетей любой сложности (CNN, RNN, трансформеры);</li><li>Обучение и тестирование моделей на CPU и GPU;</li><li>Реализация кастомных слоёв и loss-функций;</li><li>Разработка и деплой ML/AI моделей в продакшен;</li><li>Быстрая итерация гипотез с удобной отладкой.</li></ul><p>С PyTorch можно начать с простых нейронных сетей, а затем перейти к реализации современных архитектур.</p><h3>Как пользоваться</h3><p>Установим PyTorch (на CPU, для GPU потребуется версия с CUDA):</p><p>Рассмотрим кейс обучения простой нейронной сети для классификации рукописных цифр MNIST.</p><p>После обучения можно использовать torch.save() для сохранения модели и torch.load() для загрузки в продакшн.</p><h3>Почему это меняет карьеру</h3><p>PyTorch — билет в мир современной разработки AI и машинного обучения. Владение инструментом даёт <b>разработчику</b> возможность уверенно войти в области, которые продолжают оставаться топовыми на рынке: искусственный интеллект, компьютерное зрение, NLP, генерация изображений и видео и т.д.</p><p>Для <b>начинающего ML/AI-специалиста </b>PyTorch помогает лучше понять, как устроены нейронные сети, и под капотом увидеть, как происходят вычисления. Это ускоряет рост навыков и делает разработчика востребованным в исследованиях и R&amp;D-проектах.</p><p>Для <b>дата-сайентистов</b> PyTorch позволяет превратить исследовательские ноутбуки в готовые к деплою модели, благодаря PyTorch Lightning, TorchScript и ONNX.</p><p>Для<b> разработчиков, которые хотят выйти на рынок AI</b>, PyTorch — это мастхев: проекты в стартапах и крупных компаниях всё чаще строятся вокруг него. Умение писать кастомные loss-функции, проектировать сложные пайплайны обучения, настраивать обучение на кластерах и GPU — компетенции, которые существенно бустят зарплату.</p><p>PyTorch в целом помогает расширять портфолио: с ним можно создавать генеративные модели, строить LLM, участвовать в соревнованиях и работать с самыми современными подходами в машинном обучении.</p><h2>4. Polars</h2><p>Polars — современная библиотека для обработки данных в Python, созданная как альтернатива Pandas. Она использует колоночную архитектуру и многопоточность, что позволяет работать с большими объёмами данных значительно быстрее и с меньшим потреблением памяти.</p><p>Polars вдохновлена Pandas, но её API оптимизировано для производительности и удобства, а также даёт разработчику возможность писать цепочки ленивых вычислений, которые оптимизируются перед выполнением. Это делает её отличным инструментом для аналитиков, дата-инженеров и дата-сайентистов, которым нужно обрабатывать данные быстро.</p><h3>Какие задачи решает библиотека</h3><p>Polars явно есть, чем гордиться:</p><ul><li>Загрузка, очистка и преобразование больших датасетов;</li><li>Анализ данных с использованием цепочек преобразований;</li><li>Быстрая агрегация и группировка данных;</li><li>Ленивые вычисления: построение пайплайнов преобразования данных, которые выполняются только при вызове collect().</li><li>Обработка данных, которые не помещаются в память, за счёт эффективности и колоночной архитектуры.</li></ul><p>Если Pandas начинает притормаживаться на данных в несколько гигабайт, Polars обычно продолжает работать быстро, позволяя без боли обрабатывать большие CSV.</p><h3>Как пользоваться</h3><p>Установка:</p><p>Давайте загрузим данные и проведем базовые трансформации:</p><p>А вот и пример ленивых вычислений:</p><p>В чем особенность:</p><ul><li>pl.read_csv загружает данные сразу.</li><li>pl.scan_csv создаёт план вычислений для последующей оптимизации.</li><li>Используются выражения (pl.col, .with_columns, .agg), которые композируются без создания промежуточных копий, это ускоряет процесс.</li></ul><h3>Почему это меняет карьеру</h3><p>Polars меняет карьеру, потому что даёт преимущество в скорости и эффективности при работе с данными. Там, где Pandas уже не справляется, полярный медведь приходит на помощь.</p><p>Для <b>дата-инженеров</b> Polars полезен при построении ETL и пайплайнов обработки данных, где важна скорость и предсказуемое потребление ресурсов. Его можно использовать в продакшен-скриптах, для подготовки данных к ML и для автоматизации отчётности.</p><p>Для <b>дата-сайентистов </b>Polars даёт возможность анализировать больше данных за меньшее время, быстро итерировать гипотезы и ускорять исследования. Его API достаточно близок к Pandas, поэтому переход не требует месяцев переучивания.</p><p>Освоение Polars показывает работодателям, что ты не просто знаешь стандартные инструменты, но умеешь выбирать оптимальные решения для реальных задач, повышая эффективность работы команды. В эпоху роста данных это критично для любого Python-разработчика, работающего с аналитикой и машинным обучением.</p><h2>5. FastAPI</h2><p>FastAPI — современный фреймворк для создания API на Python, заточенный под скорость, асинхронность и валидацию данных из коробки. Он построен на Starlette и Pydantic, автоматически создаёт OpenAPI-документацию, поддерживает асинхронное программирование и позволяет писать производительные REST и WebSocket API с минимальным количеством кода.</p><p>Вместо долгой настройки, как у Flask или Django, в FastAPI многое готово изначально: удобная работа с запросами и ответами, декларативная валидация, документация Swagger, асинхронность и высокая производительность без лишних усилий.</p><h3>Какие задачи решает</h3><p>Задач, действительно, много:</p><ul><li>Быстрая разработка REST API для мобильных и веб-приложений;</li><li>Создание бэкенда для ML/DS моделей (деплой моделей в виде API);</li><li>Построение микросервисов с хорошей производительностью;</li><li>Реализация websocket-серверов и асинхронных API;</li><li>Подготовка внутренних инструментов или бэкендов для MVP.</li></ul><p>FastAPI помогает быстро запускать API и уверенно масштабировать его в полевых условиях. Это один из немногих фреймворков Python, который по скорости работы сопоставим с Node.js и Go.</p><h3>Как пользоваться</h3><p>Во-первых, нужно установить FastAPI и Uvicorn (используем ASGI-сервер для запуска):</p><p>Простейший API-пример с эндпоинтом GET /:</p><p>Запускаем сам сервер:</p><p>После запуска API будет доступен по адресу http://127.0.0.1:8000/. Автоматически доступна интерактивная документация Swagger по адресу http://127.0.0.1:8000/docs.</p><p>FastAPI поддерживает валидацию параметров запроса, тел запросов и путей прямо через типы Python. Например, простой эндпоинт с параметром:</p><p>При вызове http://127.0.0.1:8000/items/10?q=test FastAPI автоматически проверит, что item_id — это число, и распарсит q как строку.</p><h3>Почему это меняет карьеру</h3><p>FastAPI — билет в мир бэкенда, где скорость и чистота кода имеют довольно высокое значение. Для <b>Python-разработчика </b>это возможность быстро освоить создание API и микросервисов, не увязнув в громоздкой настройке, как в Django, и при этом получить систему, готовую к продакшену.</p><p>Для <b>ML-специалиста</b> FastAPI становится инструментом для деплоя моделей: можно обернуть пайплайн предсказаний в API, подключить авторизацию или логирование и получить работающий сервис за считанные дни.</p><p>Вообще умение быстро поднимать и поддерживать API — навык, который ценят в бигтехе и стартапах. На разработчиков, которые владеют FastAPI, часто равняются: они умеют превращать идеи бизнеса в работающие сервисы за минимальное время.</p><h2>6. Typer</h2><p>Typer — современная библиотека для создания CLI-приложений на Python с минимальным количеством кода и автоматической генерацией документации. Автор библиотеки — Себастьян Рамирес, создатель FastAPI.</p><p>Главная особенность Typer — использование type hints для автоматического парсинга аргументов командной строки. Вы получаете удобную и читаемую CLI с поддержкой автодополнения и цветного вывода за считанные минуты.</p><h3>Какие задачи решает библиотека</h3><p>Список задач такой:</p><ul><li>Создание CLI-утилит любого уровня сложности.</li><li>Быстрое прототипирование и упаковка Python-скриптов в удобные инструменты для продакшена.</li><li>Генерация подробной справки (--help) и автодополнения команд.</li><li>Облегченная поддержка и масштабирование CLI за счёт структуры и читаемого кода.</li><li>Организация CLI с подкомандами, вложенными аргументами и обработкой ошибок.</li></ul><p>Typer использует аннотацию типов и минимум шаблонного кода.</p><h3>Как пользоваться</h3><p>Установка:</p><p>Пример минимальной CLI:</p><p>Теперь можно запустить из консоли:</p><p>Результат будет такой: Привет, Алиса! Тебе 25 лет.</p><h3>Почему это меняет карьеру</h3><p>Typer меняет карьеру тем, что открывает путь к созданию удобных CLI-инструментов, которые автоматизируют рутину и повышают продуктивность.</p><p>С Typer можно быстро превращать свои Python-скрипты в надежные утилиты, которыми удобно пользоваться и другим разработчикам, и сотрудникам из других отделов. CLI-приложения часто становятся клеем инфраструктуры: они позволяют автоматизировать деплой, миграции БД, сбор данных, интеграцию с внешними API и локальную разработку.</p><p>Если вы <b>Data Scientist или ML-инженер</b>, Typer позволяет оборачивать пайплайны в CLI, которые легко запускать из Jenkins, Airflow или вручную. Если вы <b>DevOps или Backend-инженер</b>, можете создавать CLI для работы с инфраструктурой и сервисами без сложных зависимостей.</p><p>Кроме того, работа с Typer улучшает навык структурирования кода, понимание CLI, использования type hints и разработки инструментов, которые делают работу проще для других. А это, очевидно, ценится в любой команде и повышает востребованность специалиста.</p><h2>7. Rich</h2><p>Rich — библиотека Python для красивого форматирования и интерактивного отображения информации в терминале. С её помощью можно выводить цветные таблицы, маркдаун, прогресс-бары, подсвеченный синтаксис кода, деревья каталогов и логирование в понятной и привлекательной форме.</p><p>Rich создана для того, чтобы «оживить» консоль Python, сделать логи удобными для восприятия, а CLI-инструменты — профессионально выглядящими без лишних усилий. Это библиотека, которая улучшает и UX, и DX.</p><h3>Какие задачи решает</h3><p>Про красоту не забываем! Задачи следующие:</p><ul><li>Цветное и структурированное логирование, понятное при чтении логов в реальном времени.</li><li>Отображение прогресс-баров для долгих операций.</li><li>Вывод таблиц, деревьев каталогов, JSON прямо в терминале.</li><li>Подсветка синтаксиса кода для CLI-инструментов.</li><li>Создание CLI-интерфейсов, которые выглядят профессионально и современно.</li><li>Улучшение читаемости при отладке скриптов.</li></ul><p>С помощью Rich можно быстро сделать понятными даже сложные данные при отладке или демонстрации.</p><h3>Как пользоваться</h3><p>Установка Rich:</p><p>Для примера выведем таблицу с подсветкой в консоли:</p><p>В результате в терминале получится цветная таблица, которая выглядит понятно и презентабельно.</p><h3>Почему это меняет карьеру</h3><p>Rich — это библиотека, которая помогает быстро повысить качество любого CLI-инструмента или дев-опыт в команде. <b>Разработчик</b>, который использует Rich, делает свои инструменты удобными не только для себя, но и для коллег: логирование становится понятным, а отладка скриптов — наглядной.</p><p>Во многих стартапах и продвинутых командах важна скорость обратной связи при тестировании пайплайнов и автоматизаций, и Rich помогает выводить ключевую информацию максимально читаемо.</p><p>Кроме того, Rich позволяет быстро создавать CLI-интерфейсы, которые выглядят как продакшен-продукты, даже если это внутренние инструменты. Руководство будет радоваться и думать о вас как о крутом разрабе.</p><p>Для <b>дата-инженеров и разработчиков DevOps</b> Rich полезна при создании админ-утилит и при мониторинге пайплайнов, для <b>Python-разработчиков</b> — при создании библиотек и фреймворков с CLI.</p><h2>8. LangChain</h2><p>LangChain — фреймворк для создания приложений на базе LLM, например, GPT, Claude, Mistral, Gemini. Он позволяет строить цепочки обработки запросов, интегрировать LLM с данными и инструментами, добавлять память и управление состояниями, а также связывать работу модели с внешними API и базами знаний.</p><p>LangChain предоставляет удобный слой абстракции над вызовами LLM и ускоряет разработку чат-ботов, RAG-приложений, агентов с инструментами, систем анализа документов и других AI-сервисов.</p><h3>Какие задачи решает</h3><p>Список внушительный:</p><ul><li>Интеграция LLM в Python-приложения без необходимости писать тот самый клеевой код вручную.</li><li>Построение цепочек с последовательной обработкой сообщений, включая преобразования и вызовы внешних функций.</li><li>Добавление памяти в чат-боты для сохранения истории общения и контекста.</li><li>Использование агентов для динамического вызова инструментов (веб-поиск, базы данных, API).</li><li>Создание RAG-систем с интеграцией LLM и векторных БД.</li><li>Быстрая сборка прототипов LLM-приложений, которые можно развернуть в продакшен.</li></ul><h3>Как пользоваться</h3><p>Установка:</p><p>Создадим простую цепочку с чатом GPT:</p><p>Благодаря единым абстракциям, можно гибко комбинировать цепочки, память и вызов внешних инструментов, не усложняя код.</p><h3>Почему это меняет карьеру</h3><p>LangChain меняет карьеру, потому что открывает новый пласт Python-разработки в AI и LLM-инженерии, быстро превращая пользователя GPT в создателя полноценных AI-приложений. Вместо того чтобы писать хаотичный клеевой код, вы начинаете системно проектировать цепочки запросов, учитесь строить продуманные промпты и объединять их с инструментами, памятью и внешними API.</p><p>Работа с LangChain погружает в практическую LLM-инженерию: вы начинаете создавать RAG-приложения, которые умеют искать и анализировать данные перед генерацией ответа и строить агентов. Это востребовано в продуктах, где нужно подключать ИИ к базам знаний, автоматизировать задачи и разрабатывать интерактивные системы, которые реально используют модели в продакшене.</p><p>LangChain позволяет быстро собирать и запускать MVP AI-продуктов, что дает конкурентное преимущество при создании стартапов или внутренних сервисов. А ещё учит мыслить структурами и проектировать масштабируемую архитектуру LLM-приложений и видеть, как генеративный ИИ можно превратить в рабочий инструмент.</p><h2>9. SQLAlchemy</h2><p>SQLAlchemy — это мощная ORM и toolkit для работы с базами данных в Python, позволяющая писать SQL-запросы декларативно, создавать модели таблиц и управлять транзакциями в Python-коде без ручного написания SQL.</p><p>Библиотека даёт разработчику два уровня контроля:</p><ul><li>Core: низкоуровневая работа с SQL выражениями и соединениями;</li><li>ORM: высокоуровневая декларативная работа с моделями, классами и связями между таблицами.</li></ul><p>SQLAlchemy поддерживает PostgreSQL, MySQL, SQLite, Oracle и другие СУБД, давая единую абстракцию, без привязки к конкретному движку.</p><h3>Какие задачи решает</h3><p>Пул задач следующий:</p><ul><li>Описание таблиц в виде Python-классов и управление ими через сессии;</li><li>Создание, чтение, обновление и удаление данных;</li><li>Миграция SQL на декларативный стиль без потери гибкости;</li><li>Полный контроль над транзакциями и выполнением запросов;</li><li>Работа с асинхронными приложениями при создании FastAPI/Django-приложений;</li><li>Экранирование параметров, которое снижает вероятность SQL-инъекций и ошибок.</li></ul><h3>Как пользоваться</h3><p>Создадим минимальный пример для SQLite с таблицей пользователей:</p><p>Этот код создаёт базу example.db, таблицу users, добавляет туда одного пользователя и выводит всех пользователей в базе. При необходимости можно использовать SQLAlchemy Core для написания гибких запросов вручную, если нужно работать ближе к SQL.</p><h3>Почему это меняет карьеру</h3><p>SQLAlchemy меняет карьеру <b>Python-разработчика</b> тем, что даёт понимание системной работы с данными, архитектуры приложений и взаимодействия с реальными базами данных. Вы учитесь строить продуманные бэкенды, которые работают с транзакциями, миграциями, связями между таблицами и сложными выборками.</p><p>Знание SQLAlchemy открывает дорогу в мир API, микросервисов и продуктов, где требуется качественное управление данными и гибкая логика работы с БД. Работа с SQL теперь совсем не страшная.</p><h2>10. Seaborn</h2><p>Seaborn — библиотека для визуализации данных на Python, построенная поверх Matplotlib и упрощающая создание информативных и стильных графиков с минимальным количеством кода.</p><p>Она автоматически заботится о красивых стилях, цветах, разметке графиков, легендах и позволяет легко строить распределения, линейные графики, тепловые карты и другие визуализации.</p><p>Библиотека тесно интегрируется с Pandas DataFrame, позволяя использовать колонки данных напрямую для построения графиков, что делает её идеальной для EDA (разведочного анализа данных) и подготовки визуализаций для отчётов и презентаций.</p><h2>Какие задачи решает</h2><p>Визуализация безумно важна, особенно в контексте дата-аналитики. Seaborn отвечает за:</p><ul><li>Быстрое построение информативных графиков для анализа данных и поиска инсайтов;</li><li>Автоматическую обработку ошибок отображения и масштабирования, что экономит время;</li><li>Поддержку сложных визуализаций по типу ящиков с усами или тепловых карт без десятков строк кода;</li><li>Стилизацию графиков без ручных настроек Matplotlib;</li><li>Возможность добавлять статистические элементы (линию регрессии, KDE, распределение);</li><li>Интеграцию с Jupyter Notebook для интерактивного анализа данных.</li></ul><h3>Как пользоваться</h3><p>Допустим, у нас есть датасет с данными о чаевых:</p><p>В три строки мы получаем чистый и читаемый ящик с усами, показывающий, как счет за ужин распределяется по дням недели.</p><p>Для построения более сложных графиков можно использовать диаграмму рассеяния:</p><p>Тут мы добавляем цветовую кодировку по полу, чтобы увидеть зависимости между переменными.</p><h3>Почему это меняет карьеру</h3><p>Seaborn меняет карьеру, потому что даёт навык визуального анализа данных, что критично в современной аналитике и дата-инженерии. Умение быстро строить графики и видеть аномалии, распределения и взаимосвязи между переменными превращает работу с данными из слепого копания в числах в структурный анализ.</p><p>Использование Seaborn в Python-стеке помогает выделиться среди разработчиков, которые ограничиваются Pandas и текстовыми логами, ведь визуализация часто позволяет быстрее заметить закономерности и убедить команду или заказчика в правильности гипотезы.</p><p>Seaborn также учит пониманию данных через визуальные паттерны, что улучшает навыки построения моделей машинного обучения (так понятнее, какие признаки важны), и помогает создавать наглядные отчёты для продуктовых решений, где результат анализа нужно доносить до людей не из айти-индустрии.</p><p><i>А какими библиотеками пользуетесь вы? Делитесь в комментариях!</i></p>]]></content:encoded>
    </item>
    <item>
      <title>В Сети нашли каталог из 3200+ готовых ИИ-агентов под любые задачи. Можно запускать в один клик без кода</title>
      <link>https://tproger.ru/news/v-seti-nawli-katalog-iz-3200--gotovyh-ii-agentov-pod-lyubye-zadachi--mozhno-zapuskat-v-odin-klik-bez-koda</link>
      <comments>https://tproger.ru/news/v-seti-nawli-katalog-iz-3200--gotovyh-ii-agentov-pod-lyubye-zadachi--mozhno-zapuskat-v-odin-klik-bez-koda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/v-seti-nawli-katalog-iz-3200--gotovyh-ii-agentov-pod-lyubye-zadachi--mozhno-zapuskat-v-odin-klik-bez-koda</guid>
      <description><![CDATA[<p>Каталог из 3200+ ИИ-агентов и готовых автоматизаций на n8n доступен бесплатно: запускаем в один клик.  </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/v-seti-nawli-katalog-iz-3200--gotovyh-ii-agentov-pod-lyubye-zadachi--mozhno-zapuskat-v-odin-klik-bez-koda">В Сети нашли каталог из 3200+ готовых ИИ-агентов под любые задачи. Можно запускать в один клик без кода</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Slack]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Discord]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Notion]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 07 Jul 2025 12:19:01 GMT</pubDate>
      <content:encoded><![CDATA[<p>В Сети обнаружили огромный <a href="https://n8nworkflows.xyz/">каталог </a>из более чем 3200 готовых рабочих процессов и ИИ-агентов для автоматизации рутинных задач через визуальный конструктор n8n. Сервис позволяет запускать агентов в один клик, настраивать пайплайны под свои потребности и быстро собирать целые «команды» из нейросетей для маркетинга, разработки, продаж, кибербезопасности, дизайна и исследования рынков.</p><p>Больше новостей — в нашем тг-канале <a href="https://t.me/+WYtyV4-XYmdhZTMy">Представляешь</a></p><h2>Что такое n8n</h2><p>Рост использования ИИ в рутине разработки, маркетинга и бизнеса приводит к потребности в простых и гибких инструментах, которые позволяют быстро соединять модели, API и данные в работающие пайплайны. Каталог n8n даёт инженерам и продуктовым командам фору: можно за день собрать MVP своего ассистента или системы автоматизации, сократив месяцы разработки.</p><p>Кроме того, открытый характер библиотеки помогает командам учиться на чужих кейсах, улучшать процессы и участвовать в развитии сообщества.</p><p>На данный момент на сайте доступно:</p><ul><li>457 простых пайплайнов для новичков;</li><li>1349 пайплайнов среднего уровня сложности;</li><li>1440 продвинутых решений для профессионалов и команд автоматизации.</li></ul><p>Каждый агент сопровождается документацией, описанием кейсов использования и рекомендациями по настройке. Также обновляется для совместимости с последними версиями n8n.</p><p>Запуск агента в n8n обычно занимает несколько минут:</p><ol><li>Вы выбираете нужный шаблон из каталога (например, автоматический парсинг HackerNews с публикацией в Telegram, автоматическую вёрстку в Notion, управление AWS-ключами через Slack или генерацию отчётов с помощью Claude).</li><li>Импортируете шаблон в свою среду n8n (SaaS или локально). Настраиваете ключи API или доступ к нужным сервисам (Telegram, Notion, Discord, AWS, HubSpot и др.).</li><li>Запускаете и получаете работающий агент, готовый к эксплуатации без написания кода.</li><li>Все процессы визуализированы, поэтому можно легко редактировать логику работы, добавлять свои шаги (например, постобработку с помощью GPT, уведомления в Slack или отправку в CRM) и адаптировать агента под свои задачи.</li></ol><h2>Какие задачи можно автоматизировать</h2><p>В каталоге есть ИИ-агенты и пайплайны для:</p><ul><li>SMM и маркетинга (сбор лидов, управление постингом, аналитика трендов);</li><li>Кибербезопасности (мониторинг SSL, автоматические алерты, управление ключами AWS);</li><li>Разработки (поддержка TypeScript Intellisense, автоматизация CI/CD);</li><li>Продуктивности (сбор и структурирование заметок в Notion, автоматизация писем, напоминания);</li><li>Исследований (поиск и структурирование данных с помощью ИИ, генерация дайджестов);</li><li>Дизайна (подготовка медиафайлов и управление рабочими процессами);</li><li>Продаж и клиентского сервиса (онбординг клиентов, автоматические уведомления и CRM-интеграции).</li></ul><p>Эти решения помогают запускать собственных ИИ-ассистентов для узких задач, ускорять работу команд и сокращать время на рутину.</p><h3>Что есть для разработчиков</h3><p>n8n остаётся платформой с открытым исходным кодом, поэтому разработчики могут:</p><ul><li>Клонировать и адаптировать любые из 3200+ рабочих процессов под свои нужды.</li><li>Интегрировать LLM (GPT-4o, Claude, Gemini) для создания сложных агентов с мультимодальными возможностями.</li><li>Выстраивать корпоративные пайплайны и автоматизированные рабочие места для команд.</li><li>Подключать плагины и собственные ноды для кастомных сценариев.</li><li>Запускать пайплайны локально или в облаке, сохраняя контроль над данными.</li></ul><p>Если вы строите собственных корпоративных ассистентов, хотите ускорить процессы или тестируете гипотезы, библиотека n8n может стать отличным полигоном для быстрой проверки решений без написания инфраструктурного кода.</p>]]></content:encoded>
    </item>
    <item>
      <title>Архитектура BFF (Backend for Frontend): зачем нужна прослойка</title>
      <link>https://tproger.ru/articles/arhitektura-bff--backend-for-frontend---zachem-nuzhna-proslojka</link>
      <comments>https://tproger.ru/articles/arhitektura-bff--backend-for-frontend---zachem-nuzhna-proslojka?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/arhitektura-bff--backend-for-frontend---zachem-nuzhna-proslojka</guid>
      <description><![CDATA[<p>Что такое архитектура BFF. Показываем, зачем нужна прослойка Backend for Frontend. Рассматриваем преимущества и основные нюансы ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/arhitektura-bff--backend-for-frontend---zachem-nuzhna-proslojka">Архитектура BFF (Backend for Frontend): зачем нужна прослойка</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Стартапы]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[App Store]]></category>
      <category><![CDATA[CSR]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Spotify]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[NFT]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 30 Jun 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Представьте ситуацию: ваш REST API для CRM-системы отлично работает с веб-версией. Создаёте мобильное приложение для курьеров и упираетесь в стену. Эндпоинт заказов тащит 40 лишних полей с финансовой отчётностью, а нужной геолокации складов нет.</p><p>Может плодить новые эндпоинты или заставлять мобилку делать несколько запросов вместо одного? Каждый запрос жрёт трафик и батарею!</p><p>Элегантное решение — <b>архитектура Backend for Frontend (BFF)</b>. Это прослойка между клиентскими приложениями и основным API, которая адаптирует данные под потребности конкретного клиента.</p><h2>Основная идея backend for frontend</h2><p>Один API не может эффективно обслуживать разные типы клиентов. Сайт, приложение для iOS, Android, умные часы — у каждого свои потребности в данных, ограничения по производительности и особенности интерфейса.</p><p>Монолитный API создают с расчётом на универсальность — на практике это приводит к компромиссам. Веб-версии нужны данные для сортировки, мобильному приложению — минимальный набор для экономии трафика.</p><p><b>Следуя архитектуре BFF, вы можете создать логику для каждого типа клиента и не засорять основной API.</b> Вместо одного эндпоинта <i>/api/products</i>, который пытается угодить всем, появляются слои:</p><ul><li>один — оптимизирует данные для веба,</li><li>второй — для мобильных устройств,</li><li>третий — для умных часов.</li></ul><p>Обычно данные приходят в неудобном виде: несколько связанных сущностей нужно запрашивать отдельно и склеивать на клиенте. BFF берёт эту работу на себя.</p><p>Прослойка знает, что мобильному приложению нужны цены в рублях с округлением до целых, а веб-версии — точные значения в долларах. Для списка товаров мобилке достаточно названия и цены, а десктопной версии нужны ещё категории, рейтинги и количество отзывов.</p><p><b>Каждый клиент получает данные в том виде, в котором может их сразу отобразить</b>. Вместо загрузки 50 полей, из которых используется 5, BFF отдаёт только нужные данные.</p><p>«Можете добавить поле user_avatar в ответ?»</p><p>—<i> «Это сломает мобилку».</i></p><p>«Тогда сделайте отдельный эндпоинт».</p><p>—<i> «У нас нет времени».</i></p><p>С BFF этого диалога нет. Фронтенд-команда получает свой API и крутит его, как хочет.</p><p>Мобильное приложение съедает 10к запросов в секунду? Пишите BFF на Go. Веб-версию делает стажёр, который знает только JavaScript? Ставьте Node.js. Никто не заставляет выбирать одну технологию на все случаи жизни.</p><h2>Как работает backend for frontend (BFF)</h2><p>BFF размещается между клиентскими приложениями и основными бэкенд-сервисами, выполняя роль посредника. В отличие от API Gateway, который просто перенаправляет запросы, BFF трансформирует данные.</p><h3>Архитектура взаимодействия</h3><p>Классическая схема выглядит так: мобильное приложение обращается к своему BFF, веб-приложение — к своему, умные часы — к третьему. Каждый BFF знает особенности своего клиента и общается с основными сервисами на их «языке».</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/a765d5ae-2c66-4a1a-83fd-2f977ac31fa2.jpg" alt="" /><figcaption>Прослойка между клиентами и API</figcaption></figure><p>Когда мобильное приложение запрашивает список заказов, его BFF делает несколько вызовов к микросервисам:</p><ul><li>берёт базовую информацию о заказах,</li><li>подтягивает данные о товарах,</li><li>получает статусы доставки.</li></ul><p>Затем склеивает всё в один ответ, отбрасывая ненужные поля и добавляя вычисляемые значения.</p><p>Веб-версия для того же списка заказов получит расширенную информацию: подробные описания товаров, историю изменений статусов, данные для аналитики.</p><h3>Обработка и агрегация данных</h3><p>BFF не просто перекладывает данные из одного формата в другой. Он выполняет бизнес-логику.</p><p><i>Например, мобильный BFF может кешировать часто запрашиваемые данные, чтобы уменьшить количество сетевых запросов.</i></p><p>Если API возвращает цены в центах, мобильный BFF конвертирует их в рубли и округляет для отображения. Веб-версия получает точные значения с копейками для расчётов.</p><h3>Независимость и масштабирование</h3><p>Когда нагрузка на приложение растёт, масштабируется только его BFF. Проблемы с веб-версией не влияют на работу мобильных клиентов.</p><h2>4 ключевых преимущества BFF</h2><h3>Оптимизация передачи данных</h3><p>Самое очевидное преимущество — экономия трафика. Приложение не тащит 2 МБ JSON с полным каталогом товаров на мобильное устройство? BFF отдаёт только нужные поля.</p><p>Количество запросов тоже сокращается. Например, чтобы показать профиль пользователя, фронтенд делает 5 запросов:</p><ul><li>за основными данными,</li><li>аватаром,</li><li>списком друзей,</li><li>последними постами,</li><li>настройками приватности.</li></ul><p>BFF объединяет всё в один запрос, получая данные параллельно от разных сервисов.</p><h3>Упрощение фронтенда</h3><p>Половина фронтенд-кода уходит на трансформацию ответов API:</p><ul><li>парсинг дат,</li><li>группировку массивов,</li><li>вычисление производных значений.</li></ul><p>BFF может взять эту работу на себя.</p><h3>Безопасность через изоляцию</h3><p>BFF создаёт барьер между клиентами и сервисами. Мобильное приложение никогда напрямую не обращается к БД пользователей или платёжке — только через свой BFF.</p><p>Можно настроить разные уровни доступа:</p><ul><li>мобильный BFF видит только публичные данные,</li><li>API для партнёров работает в песочнице.</li></ul><p>Если мобильное приложение скомпрометировано, злоумышленник не получит доступ к внутренним сервисам.</p><h3>Независимое масштабирование</h3><p>Когда приложение попадает в топ App Store, нагрузка взлетает в разы. Но страдает только мобильный BFF — веб-версия продолжает работать стабильно. Можно быстро поднять дополнительные серверы только для мобильного трафика.</p><p>Появляется возможность экспериментировать с технологиями без риска. Хотите попробовать GraphQL для веб-версии? Внедряйте в один BFF. Тестируете новую базу данных? Подключайте к экспериментальной прослойке, не трогая продакшн.</p><h2>Когда стоит использовать backend for frontend</h2><p>BFF — инструмент для конкретных ситуаций.</p><h3>Когда интерфейсы кардинально отличаются</h3><p>Если ловите себя на мысли: <i>«этот эндпоинт нужен только для веба»</i> или <i>«мобилка использует 10% полей из ответа»</i>, — пора задуматься о BFF.</p><p>Красный флаг — когда фронтенд-разработчики начинают писать костыли для обработки «неудобных» данных. Если половина JavaScript-кода занимается парсингом и трансформацией ответов API, что-то пошло не так.</p><h3>Когда интерфейсы эволюционируют быстрее джунов</h3><p>Стартапы и продукты в активной фазе развития меняют интерфейсы каждую неделю.</p><p>Классическая проблема: дизайнеры придумали новый способ отображения товаров в каталоге. Теперь нужны дополнительные поля, другая группировка, новые фильтры.</p><p>Без BFF это означает изменения в основном API, которые могут сломать другие клиенты. С BFF — правки только в одном месте.</p><h3>Когда команды работают независимо</h3><p>Если у вас несколько фронтенд-команд, которые постоянно конфликтуют из-за API, BFF даст им свободу.</p><p>Команды получат свой API, который смогут развивать в нужном темпе. Это важно в больших компаниях, где бэкенд не успевает обрабатывать запросы от всех фронтендеров.</p><p>BFF распределяет ответственность: каждая команда поддерживает свой слой.</p><h3>Когда НЕ стоит использовать BFF</h3><p>Если у вас простое приложение с одним клиентом, BFF добавит лишнюю сложность. Если API уже идеально подходит всем клиентам, зачем что-то менять?</p><h2>3 типичные ошибки при внедрении BFF</h2><h3>Дублирование логики</h3><p>Начинается незаметно: мобильный и веб BFF нуждаются в одинаковой валидации пользователей. Разработчик копирует функцию из одного проекта в другой. Через полгода одинаковый код валидации живёт в четырёх местах, и каждое изменение превращается в квест.</p><p>Хуже, когда дублируется бизнес-логика. Расчёт скидок, обработка промокодов, правила доступа — это должно жить в основных сервисах, а не размазываться по BFF-слоям.</p><h3>Избыточная сложность вместо упрощения</h3><p>Пример: команда создаёт «универсальный BFF-фреймворк» с конфигурацией через YAML, поддержкой плагинов и собственным DSL. В итоге простое добавление поля в ответ требует изучения документации на 50 страниц.</p><p>Другая крайность — микро-BFF для каждой мелочи. Отдельный слой для авторизации, отдельный для форматирования дат, отдельный для валидации.</p><h3>Неправильная гранулярность</h3><p>Один BFF на все мобильные платформы может быть слишком общим: iOS и Android имеют разные особенности интерфейса. Но отдельный BFF для каждой версии приложения — явный перебор.</p><p>Частая ошибка — создание BFF по организационному принципу, а не по техническому. У нас три фронтенд-команды, значит нужно три прослойки. Но если все команды работают с похожими данными и интерфейсами, логичнее объединить усилия.</p><h2>Практические примеры использования BFF</h2><h3>Netflix</h3><p>Компания <a href="https://netflixtechblog.com/seamlessly-swapping-the-api-backend-of-the-netflix-android-app-3d4317155187">сделала</a> разные API для веб-версии, мобильных приложений, Smart TV и игровых консолей. Каждый BFF оптимизирован под особенности устройства, например, TV-версия предзагружает больше контента из-за медленной навигации пультом.</p><h3>Spotify</h3><p><a href="https://developer.spotify.com/documentation/web-api">Используют</a> BFF для разных клиентов: веб-плеер, мобильные приложения, десктопное приложение. Мобильный BFF агрессивно кеширует данные для офлайн-режима, веб-версия работает в реальном времени.</p><h3>SoundCloud</h3><p>Публично <a href="https://developers.soundcloud.com/blog/service-architecture-1">описывали</a> переход на BFF-архитектуру. У них отдельные слои для веб-версии и мобильных приложений, которые по-разному обрабатывают аудиопотоки и метаданные треков.</p><h2>Заключение</h2><p>Страдают все, когда один API пытается обслуживать веб-версию, мобилки и что-то ещё. Фронтенд получает неудобные данные, бэкенд обрастает костылями, пользователи — медленными приложениями.</p><p>Backend for Frontend создаёт слой между клиентами и основными сервисами. Каждый тип устройства получает API, заточенный под его потребности.</p><p>Внедряйте BFF, когда интерфейсы кардинально отличаются, продукт быстро развивается, а текущий API снижает производительность.</p><p>Ты уже программист, если читаешь это! Больше про кодинг — <a href="https://t.me/+a1v-IRDDUqI0MDhi">здесь</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Почему ваше приложение тормозит: архитектурные bottlenecks, которые никто не замечает</title>
      <link>https://tproger.ru/articles/pochemu-vawe-prilozhenie-tormozit--arhitekturnye-bottlenecks--kotorye-nikto-ne-zamechaet</link>
      <comments>https://tproger.ru/articles/pochemu-vawe-prilozhenie-tormozit--arhitekturnye-bottlenecks--kotorye-nikto-ne-zamechaet?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pochemu-vawe-prilozhenie-tormozit--arhitekturnye-bottlenecks--kotorye-nikto-ne-zamechaet</guid>
      <description><![CDATA[<p>Как найти и устранить архитектурные bottleneck'и: причины тормозов, типовые ошибки и пошаговая методика диагностики.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pochemu-vawe-prilozhenie-tormozit--arhitekturnye-bottlenecks--kotorye-nikto-ne-zamechaet">Почему ваше приложение тормозит: архитектурные bottlenecks, которые никто не замечает</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[OpenTelemetry]]></category>
      <category><![CDATA[Тимлид]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 19 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ваше приложение тормозит, хотя сервер мощный, код вроде нормальный, а метрики — не очень-то и загружены? Возможно, вы столкнулись с архитектурным bottleneck'ом — скрытым ограничением, которое убивает производительность под нагрузкой. Вместе с Никитой Ульшиным, тимлидом команды разработки архитектурных инструментов в Т-Банк и автором тг-каналов <a href="https://t.me/ulshinblog">Никита Ульшин про IT</a> и <a href="https://t.me/tech_fit">ТехнофITнес | Никита Ульшин</a>, разбираем типовые узкие места в системах, от неэффективной аллокации до однопоточных участков, и показываем пошаговый подход к их поиску и устранению.</p><h2>Почему «тормоза» — это не всегда про код</h2><p>Когда пользователь жалуется на «медленное приложение», большинство разработчиков по привычке лезет в код. Профилируем, ищем неэффективные циклы, оптимизируем до запятых. Но в реальности причина часто не в логике, а в том, что её окружает.</p><p>Современное приложение — это сложный организм: десятки микросервисов, базы данных, кэши, брокеры, сети. И тормозить может любой из этих компонентов. А ты в это время профилируешь ни в чём не виноватый for.</p><p>Вот что тормозит, когда код ни при чём:</p><p><b>Архитектура</b></p><ul><li>Цепочки вызовов: каждый хоп — +latency.</li><li>Синхронные зависимости: завис один сервис — тормозят все.</li><li>Общие ресурсы: shared state, глобальные очереди, блокировки.</li></ul><p><b>Базы данных</b></p><ul><li>Нет индексов или плохой план запроса.</li><li>N+1-запросы — особенно при неосторожной ORM.</li><li>Частый доступ к одним таблицам — гонка за IO и блоки.</li><li>Нет шардинга или репликации в масштабируемой нагрузке.</li></ul><p><b>Сеть</b></p><ul><li>Высокая задержка между регионами (особенно multi-cloud).</li><li>Потери пакетов, DNS-проблемы, нестабильность.</li><li>Отсутствие connection reuse: TLS-handshake на каждый вызов.</li></ul><p><b>Очереди и брокеры</b></p><ul><li>Один медленный потребитель тормозит всех.</li><li>Нет защиты от от backpressure или дедупликации.</li><li>Неправильные batch- и ack-настройки.</li></ul><p><b>Аллокаторы и GC</b></p><ul><li>Фрагментация памяти, нагрузка на GC.</li><li>Финалайзеры, слабые ссылки, плохо настроенный heap.</li></ul><p><b>Конфигурации</b></p><ul><li>Маленький пул соединений — пул заканчивается, запросы ждут.</li><li>Агрессивные retry-политики — система перегружается.</li><li>CPU throttling в Kubernetes — контейнеру не хватает ресурсов.</li></ul><p><b>Сериализация и форматы</b></p><ul><li>Перегруженные JSON/Protobuf.</li><li>Вложенные base64 + gzip + JSON — боли сериализации.</li></ul><h3>Почему bottlenecks остаются невидимыми до продакшена</h3><p>Многие из них —  не баги, а последствия архитектурных решений. В дев-среде всё летает, потому что:</p><ul><li>мало данных,</li><li>нет конкуренции за ресурсы,</li><li>нет распределённой нагрузки.</li></ul><p>В проде начинается хаос. Рассмотрим на конкретных примерах:</p><ul><li>На деве — 2 запроса в секунду, в проде — миллион. Кто-то запустил маркетинговую рассылку, аналитик тащит big report, а клиент ретраит ошибки.</li><li>Архитектура «в лоб»: всё синхронно, каждый сервис вызывает по цепочке десяток других. Пока нагрузка мала — все живет. Как только одно звено не выдерживает — перестает жить.</li><li>Иллюзия масштабируемости: до 100 пользователей —  всё окей, на 1000 — каскадная деградация.</li><li>«Невидимая боль» между сервисами: каждый по отдельности быстрый, но блокирует друг друга на базе.</li></ul><h2>Слои архитектуры и где в них зарыты проблемы</h2><p>Когда приложение тормозит, мы часто копаемся в отдельных компонентах — фронте, бэке, базе. Но bottleneck может быть не внутри компонента, а между ними: в конфигурации, связях, сетевых задержках, очередях вызовов.</p><p>Чтобы понять, где искать узкое место, нужно пройтись по всей цепочке — от клиента до внешних сервисов.</p><h3>На уровне клиента</h3><ul><li>Тяжёлые бандлы. Огромный JS, куча аналитики, трекеры — и вот страница загружается 8 секунд на старом телефоне.</li></ul><ul><li>Чрезмерные запросы. После загрузки — 10 fetch в секунду. API захлёбывается, браузер — тоже.</li></ul><ul><li>Нет кеша. Даже статичные справочники каждый раз грузятся заново.</li></ul><ul><li>Лаги рендеринга. Бэкенд дал ответ за 100ms, но интерфейс лагает — сложные таблицы, графики, reflow.</li></ul><h3>На уровне API Gateway / BFF</h3><ul><li>Непрозрачная маршрутизация —  скрытые таймауты, ошибки ретраев.</li><li>Сборка ответов из микросервисов — цепочка из 5 вызовов на каждый клиентский запрос.</li><li>Синхронные вызовы без деградации — если один микросервис недоступен, падает весь endpoint.</li></ul><h3>На уровне Backend / бизнес-логики</h3><ul><li>Цепочки вызовов. Один сервис вызывает другой, тот — ещё один… И так далее.</li><li>Ограниченный пул соединений —  сервис готов работать, но все worker-ы ждут ресурсы.</li><li>Логика в цикле по данным —  N+1-запросы, сериализация, дублирование работы.</li></ul><h3>На уровне базы данных / кэша</h3><ul><li>Full table scan. Работает быстро на 1000 строках. Умирает на 10 миллионах.</li></ul><ul><li>Локи и гонка за ресурсы. Один UPDATE лочит строку, остальные ждут.</li></ul><ul><li>Кэш не промахивается, но и не помогает —  stale данные, повторные чтения, инвалидация не работают, как ожидалось.</li></ul><p><b>На уровне внешних сервисов (API, брокеры, платёжки)</b></p><ul><li>Без timeout и fallback. Внешний API залип — вы вместе с ним.</li><li>QPS-лимиты. Вы не знали, а вас уже зарейт-лимитили.</li><li>Нестабильная сеть. DNS тормозит, соединения рвутся, задержки скачут между регионами.</li></ul><p>Оптимизация кода важна. Но если система тормозит, искать нужно по всей цепочке —  от кнопки на фронте до брокера в соседнем дата-центре.</p><blockquote>Есть архитектурные паттерны риска, которые часто приводят к тормозам через полгода. Во-первых, общий ресурс на всех: один Redis, один Kafka-топик, одна таблица. Пока нагрузка маленькая — ок. Потом начинается бойня за доступ. Во-вторых, микросервисный монолит: формально разделены, но живут как один. Масштабировать невозможно. В-третьих, цепочки вызовов: 5–6 сервисов на путь одного запроса. Один подвис — и вся цепочка тормозит.</blockquote><h2>Базы данных: когда даже SELECT тормозит всё</h2><p>В бэкенде одна из самых коварных фраз — «ну это же просто SELECT, что с ним будет». Ответ — сначала ничего. Но со временем появляется 10 миллионов строк, и ваш innocuous SELECT превращается в full scan, который лочит диск, ест CPU и тормозит всё, что движется.</p><p>Типичная ситуация: в таблицу пишут JSONB без нормализации и индексов. Пока строк мало — жить можно. Но при росте объёмов каждый запрос превращается в медленное последовательное чтение. Это не просто «долго», а начинает мешать соседним транзакциям: подгружаются stale данные, вытесняется кэш, система начинает проседать вся — вплоть до API.</p><p>Отдельная ловушка — смешение OLTP и OLAP нагрузки. Днём — INSERT и UPDATE от клиентов, ночью — фоновая аналитика, высчитывающая отчёт за год с десятком JOIN и чтением всей таблицы. Если все запросы идут в один инстанс, происходит конкуренция за ресурсы: аналитика сбивает кеш, вызывает блокировки, а продакшн-метрики начинают сыпаться.</p><h3>Как понять, что тормоза идут из базы, а не из бэкенда?</h3><p>Вот несколько типичных признаков:</p><ul><li>Бэкенд «висит» на запросах к базе — в логах видно, что приложение ждёт результат запроса (долгий await, query(), findMany() и т. д.).</li></ul><ul><li>Latency растёт, а CPU и память в норме — сервис сам по себе не перегружен, но ответ приходит медленно.</li></ul><ul><li>В базе фиксируются медленные запросы — например, SELECT или JOIN занимают секунды, хотя раньше проходили за миллисекунды.</li></ul><p>Чтобы подтвердить гипотезу, можно:</p><ul><li>Включить логирование SQL-запросов с таймингом;</li><li>Посмотреть трейс: если шаг DB заметно длиннее остальных — это тревожный сигнал;</li><li>Запустить EXPLAIN ANALYZE на типовые запросы и проверить, где зарыта сложность.</li></ul><h3>Архитектура доступа к данным: как закладываются тормоза</h3><p>Архитектура доступа к данным — фундамент, на котором держится производительность всей системы. Даже идеальный алгоритм или быстрый backend не спасут, если данные извлекаются медленно, неэффективно или избыточно.</p><p>На что здесь стоит обратить внимание:</p><ul><li><b>Количество и характер обращений. </b>Один пользовательский запрос не должен порождать десятки обращений к базе. Планирование кэшей, агрегаций, prefetch, нормализация — всё это часть архитектуры.</li><li><b>Уровень абстракции над данными.</b> ORM может быть удобным, но часто скрывает десятки неэффективных SELECT’ов. Нужно понимать, какие запросы реально идут в базу, и не превращать каждый use case в потенциальный bottleneck.</li><li><b>Стратегия хранения и агрегаций.</b> Если вы пытаетесь на лету агрегировать 100 миллионов строк без шардинга и партиционирования — тормоза неизбежны. Архитектура должна учитывать нагрузку, частоту агрегаций, структуру данных.</li></ul><h2>Очереди и событийные системы: скрытые замедления</h2><p>Событийные архитектуры и очереди вроде Kafka или RabbitMQ часто воспринимаются как универсальное средство от всех проблем: «Сделаем асинхронно — и всё полетит». Но это не серебряная пуля. Очередь не решает проблему — она её откладывает. А иногда сама становится bottleneck’ом.</p><p>Типовые ситуации, когда очередь тормозит систему:</p><ul><li><b>Медленные консьюмеры.</b> Очередь принимает сообщения с высокой скоростью, но обработчики не успевают, и начинается накопление беклога. В результате задержки накапливаются, SLA летит, а вы только недоумеваете, почему всё так тормозит.</li><li><b>Неправильный размер batch’ей.</b> В Kafka и аналогах размер и частота batch'ей критичны. Слишком большие — ждём, пока соберётся партия. Слишком маленькие — тратим ресурсы на лишнюю загрузку и пересылку. В итоге получаем либо высокую задержку, либо низкую производительность.</li><li><b>Неравномерное партиционирование</b>. Если сообщения распределяются по партициям неравномерно, то часть узлов будет простаивать, а часть захлёбываться под нагрузкой. Одна горячая партиция может стать bottleneck’ом всей системы.</li><li><b>Проблемы с retry.</b> Если нет чёткой стратегии повторных попыток, логирования и DLQ (dead-letter queue), битое событие может крутиться в системе бесконечно, тормозя всё остальное. Также если что-то пошло не так и включились retry-механизмы, задержка может вырасти в разы. Особенно если есть backoff или дедлоки.</li></ul><h3>Почему «асинхронно» ≠ «мгновенно»</h3><p>Асинхронность — это не про скорость, а про отложенность. Событие отправлено — но когда оно будет обработано, никто не знает. Через секунду, через минуту, через час?</p><p>Типичные причины задержек в асинхронной обработке:</p><ul><li>Очередь перегружена, и событие просто стоит в хвосте.</li><li>Обработчик падает или рестартится, и событие ждёт.</li><li>Политики повторной обработки не настроены — событие крутится бесконечно.</li><li>Слишком много этапов внутри одного воркера: валидация, запись в БД, вызов API — всё это задержки, которые суммируются.</li></ul><h3>Что происходит, когда очередь переполнена — и почему это тяжело заметить</h3><p>Когда очередь переполняется, события в ней начинают задерживаться или теряться, в зависимости от конфигурации. Но хуже всего то, что это происходит тихо. Формально система работает: события принимаются, воркеры их обрабатывают. Но обработка начинает всё сильнее и сильнее отставать.</p><p>Очередь продолжает принимать события, но обрабатываются они с огромным отставанием. Новое сообщение встаёт в хвост и ждёт своей очереди десятки секунд или минут. Такую ситуацию легко не заметить, если у вас не настроен грамотный мониторинг.</p><p>Для защиты от переполнения очереди нужно мониторить несколько важных показателей:</p><ul><li>Глубина очереди (в Kafka — consumer lag, в RabbitMQ — queue.messages_ready или queue.messages): показывает, сколько сообщений накопилось и ждёт обработки.</li><li>Publish rate: сколько сообщений в секунду публикуется.</li><li>Processing rate: сколько сообщений в секунду обрабатывается.</li><li>Утилизация ресурсов воркеров (CPU, memory, I/O).</li><li>End-to-end latency: сколько времени проходит от публикации события до его обработки.</li></ul><blockquote>Есть самые частые причины накопления сообщений:<br /><br />1) Медленные потребители, которые не успевают обработать весь поток сообщений. <br />2) Шумная архитектура: 10 сообщений там, где можно было обойтись и одним. <br />3) Неправильное масштабирование брокера (например, неправильно выбранный ключ партиционирования в Kafka).</blockquote><h2>API и микросервисы: где тормозит взаимодействие</h2><p>Микросервисная архитектура на бумаге выглядит идеально: каждый сервис автономен, команды независимы, масштабирование прозрачно. Но на практике все часто превращается в болото синхронных вызовов, где каждый сервис делает запросы в пять других.</p><h3>Что тормозит в микросервисах?</h3><p><b>Много лишних вызовов</b></p><p>Один пользовательский запрос вызывает лавину внутренних HTTP/gRPC-запросов. Каждый из них — это:</p><ul><li>сетевые задержки (latency),</li><li>сериализация/десериализация данных,</li><li>ретраи при сбоях,</li><li>риск таймаутов и обрывов.</li></ul><p>Если таких вызовов много, задержка накапливается каскадом.</p><p><b>Цепочка зависимостей</b></p><p>Классика жанра: заказ зависит от оплаты, оплата — от биллинга, биллинг — ещё от трёх микросервисов.</p><p>Если тормозит хотя бы один, сыплется всё. Получается эффект домино и каскадные отказы, где неполадка в одном звене рвёт всю цепочку.</p><p><b>Нет fallback'а и таймаутов</b></p><p>Если вызов к нужному сервису не отвечает, а у вас нет fallback'а или таймаута — всё встаёт. Особенно плохо, если вызов синхронный и блокирует поток.</p><p><b>Наносервисы</b></p><p>Иногда архитекторы увлекаются и дробят сервисы до абсурда. Начинается с «давайте переиспользуем», а заканчивается 10 API-вызовами ради одного действия.</p><p>Вместо бизнес-логики система начинает заниматься оркестрацией — координирует сама себя.</p><h2>Кэш и CDN: почему «ускорители» тоже могут тормозить</h2><p>Кэш традиционно считается палочкой-выручалочкой для производительности. «Добавим кэш — и всё полетит», — думают команды, особенно под нагрузкой. Но в реальности кэш может не только не ускорить, но и наоборот — замедлить или даже уронить систему, если использовать его без понимания.</p><p>Вот несколько типичных ошибок, которые приводят к деградации производительности:</p><h3>Невалидные или слишком агрессивные стратегии</h3><p>Если кэш живёт слишком долго — пользователи получают устаревшие данные. Если обновляется слишком часто — создаются лишняя нагрузка на базу и почти постоянные «промахи».</p><p>А если кэш сбрасывается при каждом изменении, он вообще не успевает выполнять свою роль.
В итоге: нестабильное поведение, непредсказуемая производительность и раздражённые пользователи.</p><h3>Перегрузка кэша</h3><p>Когда кэш настолько загружен, что сам по себе начинает тормозить — это уже не помощь, а вред. Такое часто случается с Redis, Memcached или in-memory решениями, особенно если они:</p><ul><li>работают на одной машине без шардинга;</li><li>содержат тяжёлые объекты;</li><li>используются как универсальный ответ на все проблемы.</li></ul><p>В таких случаях кэш из «ускорителя» может падать под нагрузкой быстрее, чем база данных.</p><h3>Кэш-миссы и лавины запросов</h3><p>Классическая проблема: TTL у популярных ключей истекает одновременно, и тысячи запросов идут мимо кэша в базу.
Это может случиться после деплоя, сброса кэша или при пиковой нагрузке.</p><p>Вместо одного запроса вы получаете 10 000, и тормозит всё. Особенно критично это для систем с CDN, где внезапное истечение кэша популярных страниц может вызвать DDoS-подобную нагрузку.</p><h3>Несогласованность кэшей</h3><p>Если в системе несколько уровней кэширования (CDN, фронтовый кэш, Redis) и они обновляются по-разному, возникает несогласованность. Один пользователь видит новые данные, другой — старые. Один сервис работает с актуальной версией, другой — с устаревшей. Начинается охота за фантомами: баги вроде есть, но не у всех.</p><h2>Вычисления и память: что не так с аллокацией</h2><p>Почему мощные сервера с десятками ядер и гигабайтами памяти тормозят? Потому что производительность упирается не в «железо», а в то, как именно это железо используется. От плохого управления памятью до блокирующих операций — в системе может быть множество узких мест, которые незаметно душат throughput.</p><h3>Частые и крупные аллокации</h3><p>Каждый раз, когда создаётся новый объект, память выделяется из кучи. При интенсивной работе (например, при парсинге JSON или обработке больших структур) это может происходить слишком часто, и тогда запускается сборщик мусора (GC).</p><p>Сборка мусора — это не бесплатная операция: она останавливает выполнение программы. Частые GC-паузы создают «плавающую» производительность, когда всё работает быстро, но время от времени подвисает даже на секунду.</p><h3>GC-паузы</h3><p>Автоматическое управление памятью — благо, но оно же и ловушка. В языках вроде Go, Java или Python невозможно точно контролировать, когда сработает сборщик. Даже задержка в 50 миллисекунд может ощутимо ударить по RPS или нарушить real-time обработку.</p><p>Некоторые компании придумывают обходные пути. Так, в Twitch <a href="https://blog.twitch.tv/en/2019/04/10/go-memory-ballast-how-i-learnt-to-stop-worrying-and-love-the-heap/">использовали</a> технику memory ballast для Go-приложений, чтобы стабилизировать поведение GC и избежать всплесков пауз.</p><h3>Синхронные и блокирующие операции</h3><p>Если операции с файлами, сетью или базой данных выполняются синхронно, поток блокируется — и в это время не может обрабатывать другие задачи. Это особенно критично, если такой поток обслуживает пользовательские запросы.</p><p>Классический пример — однопоточный web-сервер, который просто ждёт ответ от другой системы. Или библиотека, использующая mutex.Lock() в горячем участке, из-за чего десятки горутин встают в очередь.</p><h3>Ограниченные ресурсы и очереди</h3><p>Даже в многопоточном приложении можно легко создать узкое место. Например:</p><ul><li>доступ к объекту синхронизирован через mutex или RW-lock;</li></ul><ul><li>пул соединений имеет жёсткий лимит;</li></ul><ul><li>очередь задач не может масштабироваться под нагрузку.</li></ul><p>В таких случаях нагрузка растёт, а пропускная способность — нет. Всё упирается в искусственное ограничение, введённое «на всякий случай».</p><h3>Однопоточные горячие участки</h3><p>Даже в многопоточной архитектуре может оказаться, что 80% времени тратится в одном месте, которое не масштабируется — например, в процессе сериализации, расчёта или шифрования. Иногда этот участок реализован однопоточно (особенно в Node.js, Python или старом Go-коде) и становится главным тормозом системы. Под высокой нагрузкой это становится особенно заметно.</p><h2>Что делать: подход к поиску и устранению bottlenecks</h2><p>Когда система тормозит, возникает соблазн сразу «что-то сделать» — добавить кэш, увеличить ресурсы, ускорить базу. Но без системного подхода можно попасть в замкнутый круг, где проблема будет возвращаться снова и снова. Чтобы избежать этого, лучше использовать пошаговую стратегию: зафиксировать симптомы, локализовать проблему, подтвердить и только потом оптимизировать.</p><h3>Шаг 1. Зафиксировать симптомы и контекст</h3><p>Важно понять, что именно «тормозит» и в каких условиях. Типовые вопросы:</p><ul><li>Когда проявляется проблема: под нагрузкой, в пиковые часы, у конкретных пользователей?</li><li>Что именно работает медленно: API, отчёты, фоновая обработка?</li><li>Как это влияет на систему: задержки, таймауты, ошибки?</li></ul><p>Пример: пользователи жалуются, что отчёты стали строиться дольше. Вчера — 5 секунд, сегодня — 20.</p><h3>Шаг 2. Проверить очевидные метрики</h3><p>Начинаем с того, что уже доступно в мониторинге:</p><ul><li>латентность API (p50, p95, p99);</li><li>загрузка CPU, использование памяти и диска;</li><li>глубина очередей и backlog;</li><li>паузы GC;</li><li>кэш hit/miss ratio.</li></ul><p>Если латентность растёт, а CPU загружен на 20%, это может указывать на проблемы в синхронных вызовах, аллокации или неэффективной работе кэша.</p><h3>Шаг 3. Сузить область через трейсинг и логирование</h3><p>Чтобы выяснить, не «тормозит» ли другой сервис, используйте распределённый трейсинг (Jaeger, OpenTelemetry, Sentry Performance) или логирование таймингов внутри запроса.</p><p>Пример (Go, обёртка для http.RoundTripper):</p><p>Так можно увидеть, что, например, сторонний сервис отвечает 3 секунды, или Redis стал отдавать ответ за 300 мс вместо обычных 3 мс.</p><h3>Шаг 4. Воспроизвести нагрузку</h3><p>Если проблема зависит от объёма данных, воспроизведите реальный сценарий или нагрузку:</p><ul><li>используйте инструменты вроде k6, Locust, Artillery;</li><li>проверьте реальные условия (например, отчёт за 30 дней, а не за 3).</li></ul><p>Если латентность растёт нелинейно, это может быть признаком N+1-запросов, неоптимального SQL или проблем с аллокацией.</p><h3>Шаг 5. Подтвердить проблему профилированием</h3><p>Если есть подозрение на перегрузку CPU или утечку памяти, используйте профилировщики:</p><ul><li>Go — pprof;</li></ul><ul><li>Java — JFR, VisualVM;</li></ul><ul><li>Node.js — clinic.js, chrome://inspect.</li></ul><p>Пример (Go, локальный pprof):</p><p>Профиль покажет, где тратится CPU, как распределяются аллокации, как часто запускается GC и в каком коде.</p><h3>Шаг 6. Оптимизировать, перепроверить и зафиксировать</h3><p>После подтверждения проблемы можно переходить к исправлениям:</p><ul><li>кэшировать внешний вызов;</li></ul><ul><li>заменить тяжёлую сериализацию (например, на easyjson в Go);</li></ul><ul><li>убрать блокирующую операцию;</li></ul><ul><li>перейти на batch-обработку.</li></ul><p>После изменений обязательно перепроверьте метрики, чтобы убедиться, что оптимизация действительно дала эффект — и не добавила новых узких мест.</p><h2>Итоги: как не попасть в архитектурную ловушку</h2><p>Bottleneck’и возникают даже в самых технологичных проектах. Это не всегда следствие «плохого кода» — куда чаще они появляются из-за архитектурных просчётов: недооценили нагрузку, не предусмотрели масштабирование, сделали ставку на неправильное решение.</p><p>Главная проблема в том, что узкие места проявляются не сразу, а под нагрузкой. В разработке и тестах всё летает, потому что ресурсов хватает. А вот в проде — особенно при росте аудитории — на поверхность всплывает всё, что не выдерживает реального объёма данных или конкуренции за ресурсы.</p><p>Чтобы избежать таких проблем, важно не просто писать чистый код, а мыслить системно: проектировать архитектуру так, чтобы она могла жить под давлением. Вот несколько принципов, которые помогут.</p><h3>Думайте об объёмах и росте</h3><p>Архитектура должна выдерживать не только текущую нагрузку, но и разумный рост. Строить систему на «миллиард пользователей» с первого дня — избыточно. Но если вы рассчитываете, что пользователей станет в 5 раз больше через год — закладывайте это сейчас. Узкие места не любят сюрпризов.</p><h3>Настраивайте метрики с первого дня</h3><p>Без данных вы работаете вслепую. Любой анализ будет превращаться в гадание: виноват код или Redis, где тормозит — непонятно. С самого начала следите за ключевыми метриками: latency, очереди, GC, hit/miss в кэше, ошибки. Это не «доработка потом», а часть живой системы.</p><h3>Проектируйте с учётом деградации</h3><p>Любая система может начать тормозить — вопрос в том, как она себя при этом поведёт. Важно предусмотреть мягкую деградацию: таймауты, очереди, резервные сценарии, ограничение входящего трафика.</p><h3>Не усложняйте архитектуру без повода</h3><p>Микросервисы, шины, очереди, event-driven — всё это мощные инструменты. Но сложность должна быть оправданной. Простая, понятная архитектура с мониторингом и масштабируемыми точками зачастую выигрывает у перегруженной модульной схемы, которую никто не может отладить.</p><p>Bottleneck’и — это не баг, а симптом. И хороший архитектор — это не тот, кто устраняет тормоза, а тот, кто их не допускает.</p><p>Больше боли коддеров — <a href="https://t.me/+ezugB7gnIEsxNGMy">тут</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Создаём микросервис, который рекомендует, где выгоднее обменять крипту — по API и в реальном времени</title>
      <link>https://tproger.ru/articles/sozdayom-mikroservis--kotoryj-rekomenduet--gde-vygodnee-obmenyat-kriptu---po-api-i-v-realnom-vremeni-255981</link>
      <comments>https://tproger.ru/articles/sozdayom-mikroservis--kotoryj-rekomenduet--gde-vygodnee-obmenyat-kriptu---po-api-i-v-realnom-vremeni-255981?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Григорий Тюрамович]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sozdayom-mikroservis--kotoryj-rekomenduet--gde-vygodnee-obmenyat-kriptu---po-api-i-v-realnom-vremeni-255981</guid>
      <description><![CDATA[<p>Руководство для программистов: как создать сервис, который помогает выбрать лучший курс обмена криптовалюты. Работа с API, фильтрация обменников, подводные камни и честный итог.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sozdayom-mikroservis--kotoryj-rekomenduet--gde-vygodnee-obmenyat-kriptu---po-api-i-v-realnom-vremeni-255981">Создаём микросервис, который рекомендует, где выгоднее обменять крипту — по API и в реальном времени</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Быстрый старт]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Криптовалюты]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 11 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если ты хоть раз пробовал обменять криптовалюту вручную, то знаешь, как это выглядит. Один обменник предлагает хороший курс, но не работает с твоим банком. Второй — вроде бы нормальный, но курс хуже, а комиссия всплывает на последнем шаге. Третий вообще выглядит как сделанный на коленке сайт с прошлого десятилетия. И так каждый раз.</p><p>На фоне десятков сервисов, агрегаторов и P2P-площадок хочется одного — быстро, безопасно и без геморроя обменять крипту по адекватному курсу. Особенно если ты не просто энтузиаст, а хочешь автоматизировать процесс: следить за курсами, получать уведомления и делать выбор осознанно, а не тыкать вслепую в поиске надежного криптообменника.</p><p>В этой статье мы соберём микросервис, который будет в реальном времени анализировать предложения и подсказывать, где выгоднее обменять криптовалюту. Да, руками. Да, с нуля. Да, с кодом. Без лишней теории — только практика, понятная каждому, кто хоть раз писал бэкенд или работал с API.</p><p>Разберёмся, какие официальные криптообменники предоставляют данные, как фильтровать по валютам и платёжкам, как учитывать комиссии и что делать, если тебе нужно обменять криптовалюту на рубли или даже на наличные. В процессе ты поймёшь не только как работает обмен крипты, но и почему многие разработчики в итоге идут не в код, а в уже готовые решения.</p><h2>Архитектура сервиса: что мы вообще собираем</h2><p>Идея простая: у нас есть десятки криптообменников, у каждого — свои курсы, комиссии и условия. Ручной перебор — не вариант. Значит, нужен сервис, который по заданным параметрам сам найдёт лучший вариант обмена и покажет его тебе в удобном виде.</p><p>Что должно быть на выходе: ты передаёшь в сервис, например: «Хочу обменять криптовалюту USDT на рубли через банковскую карту», а он тебе в ответ: «Вот три предложения, сортированы по выгоде и надёжности. Если хочешь, сервис может ещё и отправить тебе уведомление, когда курс станет подходящим».</p><p>Как это устроено:</p><ol><li>Источник данных<br />Нам нужно получать актуальные курсы с разных платформ. Желательно не писать свои парсеры для каждого сайта — у многих официальных криптообменников есть открытые API. Ещё лучше — использовать агрегатор, который уже всё это собирает.</li><li>Фильтрация и логика выбора<br />Не каждый обменник подходит. У кого-то нет вывода на карту, у кого-то курс хороший, но комиссия грабительская. Придётся учитывать кучу параметров: тип валюты, доступность в России, платёжные методы, лимиты.</li><li>Простая точка входа<br />Это может быть консольный скрипт, API, веб-интерфейс или даже Telegram-бот. Главное — чтобы ты мог быстро получить ответ на вопрос: «Где сейчас выгоднее обменять крипту?»</li><li>Автоматизация<br />Желательно, чтобы всё это работало без участия человека. В идеале — ты один раз настраиваешь фильтры, и дальше сервис сам мониторит ситуацию. Хочешь — получаешь пуш, хочешь — просто заходишь и смотришь.</li></ol><h2>Где брать данные: API-агрегаторы против самописного парсинга</h2><p>Первая мысль: «Окей, я сейчас возьму список криптообменников, напишу парсер под каждый, подтяну курсы, и будет у меня свой умный мониторинг». Но на практике всё оказывается не так просто.</p><p>Во-первых, многие обменники вообще не отдают данные в открытом виде. У кого-то нет API, у кого-то курс виден только после логина или выбора платёжки. У кого-то защита от ботов, редиректы, капчи, анти-DDoS и прочие радости.</p><p>Во-вторых, даже если ты спарсишь курс — он почти всегда будет «в вакууме»: без учёта комиссии, ограничения по сумме, или без указания, что это только для новых клиентов. А значит, ты получаешь данные, на которые нельзя опираться.</p><p>Ещё одна проблема — актуальность. При обмене криптовалюты важны секунды. Ты можешь спарсить курс, но пока ты его покажешь пользователю — он уже устарел. Особенно это критично, если человек хочет обменять криптовалюту на рубли по точной сумме.</p><p>Что делать? Использовать API-агрегаторы. Это такие сервисы, которые уже собрали десятки официальных криптообменников, следят за их курсами, учитывают комиссии, доступность и форматируют данные в единый стандарт.</p><p>Такие агрегаторы обычно дают:</p><ul><li>нормальное API без сюрпризов;</li><li>актуальные курсы в реальном времени;</li><li>фильтры по валютам, платёжкам, регионам (например, только криптообменники в России);</li><li>возможность видеть, кто работает с наличкой, кто с банками, кто вообще жив.</li></ul><p>Если ты хочешь не просто поиграться, а сделать рабочий инструмент — парсить вручную точно не стоит. Слишком много сил, а результат — нестабильный. Лучше взять нормальный источник и потратить время на логику фильтрации и вывод.</p><h2>Быстрый старт: пишем простейший клиент на Python</h2><p>Допустим, ты решил сам посмотреть, где сейчас можно обменять криптовалюту. Мы уже договорились, что не будем парсить сайты руками — берём агрегатор с открытым API, например, <a href="https://exnode.ru/?utm_source=tproger&amp;utm_medium=22.05.2025(g)">Exnode</a> или любой другой, у кого адекватная документация.</p><p>Цель на этом этапе — получить список обменников с курсами и отфильтровать, где реально выгодно обменять крипту на нужную тебе валюту, скажем, на рубли.</p><p>Простейший скрипт на Python может выглядеть так:</p><p>Что тут происходит:</p><ul><li>мы запрашиваем курс обмена с USDT на рубли;</li><li>получаем список предложений от разных криптообменников;</li><li>выводим курс и комиссию.</li></ul><p>На этом этапе ты уже можешь видеть, где выгоднее обменять криптовалюту на рубли, а где предложение так себе. Причём это только базовый пример — можно легко докрутить фильтры по платёжной системе (например, карты Тинькофф или Сбера), включить данные по лимитам, скорости и надёжности обменника.</p><p>Данные от агрегаторов — это по сути твоя опорная точка. Уже с них можно построить более сложную логику, подключить автослежение или выдачу в бота.</p><h2>Фильтрация и выбор лучшего обменника</h2><p>После получения списка предложений от различных криптообменников с помощью API, следующим шагом будет фильтрация и выбор наиболее выгодного варианта. В этом процессе важно учитывать не только курс обмена, но и дополнительные параметры, такие как комиссии, доступность методов вывода и надежность обменника.</p><h3>1. Учет комиссий</h3><p>Курс обмена может быть привлекательным, но скрытые комиссии способны существенно снизить выгоду от сделки. Поэтому необходимо учитывать общую сумму, которую вы получите после всех вычетов. Например, обменник может предлагать курс 100 рублей за USDT, но с комиссией 2%, в то время как другой предлагает 98 рублей без комиссии. В таком случае второй вариант может быть более выгодным.</p><h3>2. Способы вывода средств</h3><p>Важно учитывать, какие методы вывода средств предлагает обменник. Некоторые работают только с банковскими картами, другие предлагают наличный расчет или переводы на электронные кошельки. Если вам необходимо обменять криптовалюту на рубли и получить наличные, убедитесь, что выбранный обменник предоставляет такую возможность.</p><h3>3. Надежность и репутация</h3><p>Перед выбором обменника стоит изучить отзывы других пользователей и проверить его репутацию. Надежные криптообменники обычно имеют положительные отзывы и работают на рынке не первый год. Также стоит обратить внимание на наличие лицензий и соответствие требованиям законодательства.</p><h3>4. Географическая доступность</h3><p>Если вы предпочитаете офлайн-обмен, важно учитывать расположение офисов обменника. Например, такие обменники, как Insight, BitOkk и EastChange, имеют офисы в Москве и других крупных городах России, что делает их удобными для личного посещения.</p><h3>5. Примеры обменников</h3><p>Рассмотрим кратко три популярных обменника:</p><ul><li><a href="https://insight-cash.com/?utm_source=tproger&amp;utm_medium=22.05.2025(g)">Insight</a>: Предлагает низкие комиссии, быстрый обмен и поддержку различных криптовалют. Имеет офисы в Москве и Санкт-Петербурге.</li><li><a href="https://bitokk.biz/?utm_source=tproger&amp;utm_medium=22.05.2025(g)">BitOkk</a>: Известен широким выбором криптовалют и высокой скоростью обслуживания. Предлагает выгодные курсы и работает без верификации для небольших сумм.</li><li><a href="https://eastchange.io/?utm_source=tproger&amp;utm_medium=22.05.2025(g)">EastChange</a>: Специализируется на обмене USDT и крупных сделках. Предлагает фиксированный курс на 1 час и возможность онлайн-бронирования суммы перед визитом.</li></ul><p>При выборе обменника важно учитывать все вышеперечисленные факторы, чтобы обеспечить безопасность и выгодность сделки.</p><h2>UI или бот? Мини-фронт на Flask или уведомления в Telegram</h2><p>Когда у тебя уже есть рабочая логика и ты получаешь актуальные курсы от надежных криптообменников, возникает вопрос: как этим всем пользоваться? Вариантов два — делать фронт или завести простого Telegram-бота.</p><h3>Вариант 1: веб-интерфейс на Flask</h3><p>Если хочется что-то визуальное, можно быстро собрать минималистичный фронт на Flask. Это буквально 20–30 строк кода, чтобы показать таблицу с результатами. Пользователь заходит, вводит параметры (что хочет обменять, на что, куда вывести), и получает отсортированный список обменников с указанием курсов и комиссий.</p><p>Для разработчика это плюс: можно отлаживать логику прямо в браузере, быстро добавлять фильтры и визуализировать результат. Плюс это сразу наглядный инструмент, если кто-то ещё кроме тебя будет им пользоваться.</p><h3>Вариант 2: Telegram-бот</h3><p>Бот — это удобный способ получать информацию на ходу. Например, ты хочешь обменять криптовалюту на наличные — пишешь боту, он тебе выдаёт список с актуальными предложениями. Или настраиваешь алерты: как только курс стал выше X — получаешь сообщение.</p><p>Для реализации можно использовать aiogram или python-telegram-bot. API-ответы ты уже умеешь обрабатывать, осталось только прикрутить кнопку /start и минимальное меню.</p><p>Telegram хорош тем, что не требует разворачивать сервер, не нужен фронт, и всё работает прямо в чате. Особенно если ты хочешь этим пользоваться сам — это один из самых практичных вариантов.</p><h2>Подводные камни</h2><p>С одной стороны, идея кажется простой: подключил API, получил курс, показал пользователю, где выгоднее обменять крипту. Но на практике всплывает куча нюансов, которые лучше учитывать заранее.</p><h3>1. Актуальность данных</h3><p>Даже если ты используешь агрегатор, курсы могут обновляться не каждую секунду. А на волатильном рынке 1–2 минуты — это уже критично. Ты думаешь, что обменяешь криптовалюту по одному курсу, а на деле получишь совсем другой.</p><p>Плюс не все обменники дают точные данные в реальном времени. Иногда они показывают примерный курс или средний по рынку, а финальные условия ты видишь уже на этапе оформления.</p><h3>2. Комиссии, которых не видно</h3><p>Бывает, что курс выглядит отлично, а потом на последнем шаге прилетает комиссия, и выгода улетает. Или минимальная сумма сделки оказывается больше, чем ты хотел. Поэтому просто выводить курс недостаточно — нужно учитывать и проценты, и лимиты, и метод вывода (карта, наличные и так далее).</p><h3>3. Геоограничения</h3><p>Не все криптообменники в России работают одинаково. Кто-то обслуживает клиентов только по паспорту. Кто-то просит селфи с табличкой. Кто-то вообще закрывает доступ из определённых регионов. Поэтому важно не просто собрать список предложений, а ещё и понимать, кому они доступны.</p><h3>4. Надёжность</h3><p>Даже если курс супервыгодный — это ещё не значит, что обменник честный. Есть история с липовыми предложениями: на сайте всё красиво, а потом начинаются заморозки, проверки, возвраты. В крайнем случае — просто не приходит перевод.</p><p>Даже популярные и вроде бы официальные криптообменники иногда косячат. А если ты хочешь обменять криптовалюту на наличные — тут вообще всё должно быть идеально: ты же идёшь в реальный офис или встречаешься с курьером.</p><h3>5. Поддержка и баги</h3><p>Ты можешь написать идеальный код, но если API внезапно начнёт отдавать 500 или изменится структура ответа — всё развалится. А если ты завёл Telegram-бота, который не умеет обрабатывать такие сбои, он начнёт спамить ошибками.</p><h2>А нужно ли это вообще?..</h2><p>Вот ты всё это собрал: API, фильтрацию, Telegram-бота или веб-интерфейс. Всё работает, данные идут, курс считается. Красота. Но давай по-честному — тебе вообще нужно это поддерживать?</p><p>Если ты просто хочешь обменять криптовалюту на рубли или на карту без мороки — стоит ли городить систему с логикой, логами, падениями и багами? Даже если ты всё автоматизировал — всё равно приходится следить, обновлять, чинить.</p><p>Это крутой проект, если ты хочешь разобраться, потренироваться, поиграться с API. Или если ты строишь свой продукт. Но если цель — быстро и безопасно обменять крипту в жизни, а не на коде — не проще ли просто пойти в нормальный агрегатор?</p>]]></content:encoded>
    </item>
    <item>
      <title>С помощью чего выучить SQL в 2025 году?</title>
      <link>https://tproger.ru/articles/s-pomoshhyu-chego-vyuchit-sql-v-2025-godu-</link>
      <comments>https://tproger.ru/articles/s-pomoshhyu-chego-vyuchit-sql-v-2025-godu-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Влад Полбенников]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/s-pomoshhyu-chego-vyuchit-sql-v-2025-godu-</guid>
      <description><![CDATA[<p>Как выучить SQL с нуля в 2025? Сравниваем 6 платформ: SYNC STUDY, SQL Academy, Karpov Courses и другие. Бесплатные и платные курсы, задачи из реальной аналитики, поддержка PostgreSQL. Советы по выбору для новичков и профессионалов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/s-pomoshhyu-chego-vyuchit-sql-v-2025-godu-">С помощью чего выучить SQL в 2025 году?</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 01 Jun 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>SQL остаётся ключевым инструментом для работы с данными. Даже базовые знания увеличивают шансы на трудоустройство в аналитику и Data Science. Но найти подходящий тренажёр или курс сложно: одни платформы слишком поверхностные, другие — дорогие, а третьи не дают практики в реальной среде.</p><h2>Как выучить SQL: ТОП-6 платформ для обучения</h2><p>Протестировав много ресурсов, я выбрал 6 лучших. Каждый подходит для разных целей: от тренажеров до подготовки к сложным собеседованиям.</p><p><b>Критерии оценки</b></p><ul><li>Контент: глубина тем (от SELECT до оптимизации запросов), задачи из реальной работы, подготовка к собеседованиям, поддержка сообщества.</li><li>Технические аспекты: мобильная версия, своя IDE, сертификат, адаптация под РФ, поддержка PostgreSQL.</li></ul><h3>SYNC STUDY</h3><p>Ссылка: <a href="https://sync.study/">SYNC STUDY</a></p><p>Для кого: Новички, профи и те, кто готовится к собеседованиям.</p><ul><li>Глубина погружения: Полный цикл — от основ (WHERE, JOIN) до оконных функций и создания витрин.</li><li>Собеседования: Отдельный модуль с кейсами из практики и с теоретическими вопросами с собеседований.</li><li>Практика: Задачи на расчет LTV, ABC-анализ, парсинг логов.</li><li>Техническая часть: Удобная мобильная версия, своя IDE. Полная адаптация под РФ.</li></ul><ul><li>Решения воспроизводятся в реальной среде PostgreSQL.</li></ul><p>Минусы:</p><ul><li>Поддержка в процессе прохождения: отсутствует.</li><li>Сертификат по окончании курса: нет.</li></ul><h3>SQL Academy</h3><p>Ссылка: <a href="https://sql-academy.org/ru">SQL Academy</a></p><p>Для кого: Новички и практикующие разработчики.</p><ul><li>Глубина погружения: От простых запросов до триггеров и оптимизации. Подробные примеры из e-commerce.</li><li>Собеседования: Нет отдельного раздела, но есть задачи уровня FAANG.</li><li>Практика: Симулятор с интерактивными заданиями (например, расчет Retention Rate).</li><li>Поддержка: Форум, где можно обсудить решение.</li><li>Техническая часть: Своя IDE, работает на мобильных. Сертификат — после финального экзамена.</li><li>Бесплатный доступ.</li></ul><p>Минус: Мало информации по работе с большими данными (например, партицирование).</p><h3>Karpov Courses</h3><p>Ссылка: <a href="https://karpov.courses/simulator-sql">Karpov Courses</a></p><p>Для кого: Новички в IT, менеджеры, аналитики, дата-сайентисты и все, кто хочет освоить SQL и продуктовую аналитику с нуля.</p><ul><li>Глубина погружения: Акцент на практику — от основ SQL до продвинутых тем (оконные функции, объединения) и решения реальных продуктовых задач.</li><li>Собеседования: Кейсы из собесов Альфа-Банка, Сбера, Ozon.</li><li>Практика: 150+ SQL-задач на симуляторе. Работа над кейсом аналитика сервиса доставки: расчет бизнес-метрик, анализ данных, проверка гипотез.</li><li>Поддержка: Доступ к чату сообщества для общения и вопросов.</li><li>Техническая часть: IDE с подключением к реальной PostgreSQL и инструмент для визуализации Redash.</li></ul><ul><li>Бесплатный доступ ко всем материалам, симулятору и инфраструктуре.</li></ul><h3>SQL-ex.ru</h3><p>Ссылка: <a href="https://sql-ex.ru/">SQL-ex.ru</a></p><p>Для кого: Для тех, кто любит учиться через решение задач.</p><ul><li>Глубина погружения: Более 500 задач — от простых SELECT до хранимых процедур.</li><li>Собеседования: Нет.</li><li>Практика: Олимпиадные задания (например, расчет скользящего среднего без оконных функций).</li><li>Поддержка: Форум с энтузиастами.</li><li>Техническая часть: Устаревший интерфейс, нет мобильной версии.</li></ul><p>Минус: Теория подается фрагментарно.</p><h3>SQLZoo</h3><p>Ссылка: <a href="https://sqlzoo.net/wiki/SQL_Tutorial">SQLZoo</a></p><p>Для кого: Новички, которые хотят попробовать SQL бесплатно.</p><ul><li>Глубина погружения: Базовый уровень + JOIN, подзапросы.</li><li>Собеседования: Нет.</li><li>Практика: Интерактивные задачи с автоматической проверкой.</li><li>Поддержка: Нет сообщества.</li><li>Техническая часть: Работает на мобильных, своя IDE.</li></ul><p>Минус: Нет продвинутых тем (CTE, оптимизация).</p><h3>Stepik</h3><p>Ссылка: <a href="https://stepik.org/catalog/42">Курсы на Stepik</a></p><p>Для кого: Для системного изучения с нуля.</p><ul><li>Глубина погружения: Полный курс с видеоуроками — от основ до анализа в Python.</li><li>Собеседования: Нет.</li><li>Практика: Задачи на анализ реальных датасетов (например, Airbnb).</li><li>Поддержка: Обсуждения к каждому уроку.</li><li>Техническая часть: Поддержка PostgreSQL, сертификат.</li></ul><p>Минус: Мало задач на оконные функции.</p><h2>Итог: Какую платформу выбрать?</h2><ul><li>Для новичков: SQL Academy (бесплатно) или Stepik (структурный курс).</li><li>Для подготовки к собеседованиям: SYNC STUDY или Karpov Courses (бесплатно).</li><li>Для углубленного изучения: Karpov Courses (аналитика) или SQL-ex.ru (практика).</li><li>Для мобильного обучения: SYNC STUDY или SQLZoo.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Как TanStack Query ускоряет работу с API и сокращает код</title>
      <link>https://tproger.ru/articles/kak-tanstack-query-uskoryaet-rabotu-s-api-i-sokrashhaet-kod</link>
      <comments>https://tproger.ru/articles/kak-tanstack-query-uskoryaet-rabotu-s-api-i-sokrashhaet-kod?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дмитрий Скляр]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-tanstack-query-uskoryaet-rabotu-s-api-i-sokrashhaet-kod</guid>
      <description><![CDATA[<p>Использование TanStack Query дает разработчикам возможность упростить работу с API, сократить дублирование кода и ускорить разработку. Рассказываем о проблемах, связанных с использованием API, и соответствующих решениях для повышения эффективности разработки.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-tanstack-query-uskoryaet-rabotu-s-api-i-sokrashhaet-kod">Как TanStack Query ускоряет работу с API и сокращает код</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Redux]]></category>
      <category><![CDATA[Xen]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 28 May 2025 14:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Представьте: вы — фронтенд-разработчик, и постоянно сталкиваетесь с рядом проблем. Еще один endpoint, еще один запрос, еще десяток строк почти идентичного кода. Вручную прописываете типы, парсите ответы, обрабатываете ошибки, обновляете кэш… А через неделю бэкенд-команда меняет API — и все, что вы строили, рассыпается как карточный домик.</i></p><p><i>Так случалось, пока не появились инструменты вроде <a href="https://tanstack.com/query/latest">TanStack Query</a> и не родились «обертки», которые уменьшают объемы рутины. Как перестать тонуть в запросах на разработку API и начать дышать свободно, рассказывает Дмитрий Скляр, старший разработчик компании Axenix. </i></p><h2>API: нервная система цифрового мира</h2><p>В современном ИТ-ландшафте API давно перестал быть просто техническим термином. Теперь он — один из столпов, на котором держится цифровая цивилизация.</p><p>Философия современной разработки давно сместилась от принципа «сделай все сам» к парадигме «собери из лучших компонентов». API стал языком, на котором взаимодействуют цифровые сервисы. Он превратил ИТ-ландшафты и интернет из собрания разрозненных приложений и сайтов в единую живую экосистему, где каждый элемент может взаимодействовать с другим.</p><p>Когда разработчик использует API картографического сервиса, ему не нужно разбираться в геоданных или алгоритмах прокладки маршрутов — он просто отправляет запрос и получает готовое решение. Это похоже на то, как мы пользуемся электричеством: не нужно понимать, как работает электростанция, чтобы включить свет в комнате.</p><p>Но настоящую революцию API совершил в бизнесе, создав целые экосистемы цифровых услуг. Такие компании, как Stripe, Twilio или Plaid построили свои империи именно на API, предоставляя другим разработчикам готовые «кирпичики» для создания финансовых, коммуникационных или аналитических сервисов.</p><p>Внутри крупных компаний API выступают в роли «дипломатов» между микросервисами и ИТ-системами, позволяя разным командам работать независимо, но при этом сохранять общую согласованность. Когда маркетинговая система запрашивает данные о продажах, а сервис логистики получает информацию о новых заказах — все это происходит через четко определенные API-контракты, которые делают сложные системы управляемыми и гибкими.</p><h2>Боль, которую никто не замечает</h2><p>Но не все так просто и далеко не так радужно.</p><p>Да, формально API — это универсальный мост, например, между фронтендом и бэкендом. На практике же он часто напоминает шаткую подвесную конструкцию: данные приходят в разном формате, документация устаревает еще до релиза, а поля user_name и username существуют одновременно просто потому, что «исторически сложилось».</p><p>Типичный сценарий: вы пишете код для запроса списка товаров, все типизируя и описывая модели — 50 строк. Добавляете фильтрацию — еще 30 строк. А через месяц бэкенд меняет структуру ответа, забывает предупредить — и вы тратите день на поиск багов в трех разных местах.  И самое обидное: 80% этого кода — копипаст. Проверка ошибок, трансформация данных, инвалидация кэша — все одно и то же, но плодится как вирусы.</p><p>Сюда можно добавить также сложность поддержки — API меняется, код устаревает.</p><p>Другой момент: код для каждого API-метода имеет схожую структуру. Повторяются основные шаблоны, а различия лишь в типах данных и отдельных деталях. Чем больше API-методов, тем сложнее отслеживать изменения в коде и поддерживать его в актуальном состоянии.</p><p>В итоге — дублирование кода, которое усложняет приложение, снижает его читаемость и замедляет разработку новых функций. Документация? Либо устарела, либо ее вообще не писали.</p><h2>Спасение — в системе</h2><p>Однажды наши разработчики устали писать однотипные хуки, чинить сломанные запросы и объяснять новичкам, что где находится, почему именно так это работает и почему нельзя просто взять и использовать что-то другое. Устали писать однотипный код для каждого запроса, захотели минимизировать ошибки и ускорить разработку, а также сделать работу с API более структурированной и понятной. Также у команд назрела потребность в скорейшем включении в проект новых разработчиков. Для всех этих задач подходит одно решение: унифицированный подход к API, который также наводит порядок в данных и отчетах, упрощая аналитику и логику приложения.</p><p>Тогда и родилась идея фабрики API — слоя абстракции, который скрывает рутину. Для этого мы привлекли возможности <a href="https://tanstack.com/query/latest">TanStack Query</a>, семейство библиотек для управления состоянием данных (data fetching) в клиентских приложениях. Помимо <a href="https://tanstack.com/query/latest">TanStack Query (ранее React Query)</a>, к этому классу инструментов также относятся: RTK Query (из Redux Toolkit), Apollo Client (для GraphQL) и SWR.</p><p>Их общая философия: «делать рутину невидимой для разработчика». Рассмотрим Конкретные проблемы и их решения.</p><h3>Однотипные хуки для каждого запроса</h3><p>В большинстве проектов без дополнительной абстракции каждый хук под API-запрос пишется вручную. Меняется только URL и параметры, а структура остаётся одинаковой: queryKey, queryFn, опции запроса. Это быстро приводит к копипасту, дублированию логики и усложнению поддержки.</p><p>Например, для каждого ресурса вроде пользователей, продуктов, заказов и т.д. приходится повторять одну и ту же конструкцию. Если нужно изменить поведение запроса (например, добавить retry или staleTime), правки необходимо делать в десятках мест.</p><p><b>Решение: Универсальная обёртка над хуками TanStack Query</b></p><p>Создание единой функции-генератора для хуков позволяет избавиться от повторяющегося кода. Она принимает ключ, функцию запроса и опциональные параметры — и возвращает сразу «пачку» готовых хуков.</p><p>Такой подход:</p><ul><li>снижает количество шаблонного кода;</li><li>упрощает масштабирование;</li><li>централизует поведение всех запросов;</li><li>позволяет быстро адаптироваться к изменениям (например, добавить логирование, типизацию, трансформации и т.п.).</li></ul><h3>Хрупкость при изменении API</h3><p>В типичном приложении без централизованной трансформации мы напрямую используем ответ от бэкенда. Любое изменение формата требует правок в типах, в местах использования данных, и часто приводит к багам.</p><p><b>Решение: Централизованная трансформация данных +</b> <a href="https://github.com/typestack/class-transformer">class-transformer</a>.</p><p>С помощью <a href="https://github.com/typestack/class-transformer">class-transformer</a> можно объявить классы сущностей и задать правила преобразования один раз.</p><p>Плюсы:</p><ul><li>Все данные автоматически приходят в нужном виде;</li><li>Компоненты работают с гарантированно типизированными данными;</li><li>Один источник правды: при изменении API – правим только Entity-класс;</li><li>Удобно масштабируется, особенно если API большое и сложное.</li></ul><h3>«Мусор» в данных и отчётах</h3><p><b>Решение: Валидация данных при трансформации (например, через class-validator); автоматическая синхронизация кеша (актуальные данные во всём приложении).</b></p><p>Почему это лучше ручного подхода? Смотрите: строк кода на 1 endpoint при ручном управлении <b>потребуется 30+</b>, а <b>с фабрикой —  5-10</b>. Времени для добавления нового поля —  1<b> час вручную, с фабрикой —  5 минут</b>. Количество мест для правки при изменении API —  вручную их много, с фабрикой — лишь одно.</p><p>Реальный кейс: в проекте с 50+ endpoint’ами переход на фабрику <b>сократил код на 70%</b>. Разработчики перестают быть «переводчиками» между API и интерфейсами сервисов и приложений, а сосредотачиваются на бизнес-логике. Как сказал один тимлид: <i>«Теперь мы не фиксим баги данных, а делаем фичи, которые нравятся пользователям»</i>.</p><p>Еще пример: вместо пяти отдельных хуков для CRUD-операций фабрика дает одну функцию createApi(). Вместо ручного парсинга — автоматическую трансформацию данных через <a href="https://github.com/typestack/class-transformer">class-transformer</a>. А главное — единые правила игры для всего проекта.</p><p>Как это работает? Представьте, что вы говорите системе: «Вот endpoint для товаров, вот их модель данных, вот правила валидации» —  а все остальное она делает за вас. Хотите получить товар по ID? Пишете useGetByIDQuery. Нужно обновить? —   useUpdatetMutation. И никакого шаманства с ручным описанием каждого хука.</p><p>Но главное — когда бэкенд меняет API, правки нужны только в одном месте. А новые разработчики перестают спрашивать: <i>«Почему у нас три разных способа загрузить список пользователей?»</i>.</p><h2>Как договориться и не сойти с ума</h2><p>Проблема в том, что без четкого контракта, набора правил и подходов фронтенд- и бэкенд-разработчики живут в параллельных реальностях. Один думает, что данные придут в camelCase, другой шлет их в snake_case. Один ожидает массив, другой неожиданно подсовывает null. Итог —  бесконечные баги, исправления «на живую» и испорченные нервы.</p><p>Решение? Четкий контракт. Простой, прозрачный, однозначный. В нем должны быть:</p><ol><li>Единые правила именования — если бэкенд отдает snake_case, фронтенд не должен гадать, будут ли остальные поля в camelCase, или, например, если в одной модели данных full_name , в другой не будет fullname и так далее.</li><li>Единый формат запросов и ответов.</li><li>Договоренности о структуре URL, формате данных и кодах ошибок.</li><li>Строгая типизация — TypeScript-интерфейсы, которые знают, какие поля обязательны, а какие могут отсутствовать.</li><li>Документация, которая не врет — если Swagger говорит, что поле email есть, оно должно быть. Всегда.</li></ol><p>И самое главное — этот контракт должен соблюдаться. Если бэкендеры меняют API, они обязаны предупредить. Иначе фронтенд превращается в сапера, который каждое утро разминирует прод.</p><p>Но, как правило, контракт сделать тяжело.  Каждый видит REST по-своему: разные URL, форматы данных, обработка ошибок. Модели данных непоследовательны — поля то есть, то их нет, вложенность меняется. Документации либо нет, либо она устарела, так что API изучаем методом проб и ошибок. От такого надо отказываться сразу и стараться договорится на берегу.</p><p>Для унификации и строгого соответствия данных мы используем <a href="https://github.com/typestack/class-transformer">class-transformer</a>: автоматически приводим данные к нужным форматам, вместо работы с сырыми JSON-объектами. Так получаются экземпляры классов с методами и свойствами. Далее убираем ручную обработку и проверки данных, преобразовываем вложенные структуры и применяем кастомные трансформации.</p><h4>Что получаем в итоге?</h4><p>Когда контракт есть, а обертка API готова, магия начинает работать:</p><ul><li><b>Простота использования</b>: вместо десятков хуков — единая фабрика createApi(). Меньше boilerplate-кода.</li><li><b>Мощные возможности</b>: данные приходят уже в нужном формате без ручных проверок. Кэш, инвалидация и оптимизации —  <a href="https://tanstack.com/query/latest">TanStack Query</a> делает за вас всю грязную работу.</li><li><b>Новички влетают в проект: </b>больше не нужно объяснять, почему useGetEntity в одном компоненте работает не так, как в другом.</li><li><b>Активное сообщество: </b><a href="https://tanstack.com/query/latest">TanStack Query</a> —  тысячи разработчиков, готовых ответить на вопросы. Здесь можно найти примеры для любых кейсов: от интеграции с <a href="https://nextjs.org/">Next.js</a> до кастомного кеширования.</li><li><b>Нет ограничений по использованию: </b><a href="https://tanstack.com/query/latest">TanStack Query</a> —  не только для React, есть версии для <a href="https://tanstack.com/query/latest/docs/framework/vue">Vue</a>, <a href="https://tanstack.com/query/latest/docs/framework/svelte">Svelte</a> и даже <a href="https://tanstack.com/query/latest/docs/framework/solid">Solid.js</a>. Также работает с любым API — REST, GraphQL, WebSockets.</li><li><b>Работа с SSR без боли: </b>готовая интеграция с <a href="https://nextjs.org/">Next.js</a>, <a href="https://remix.run/">Remix</a> и другими фреймворками. При этом данные, полученные на сервере, автоматически передаются на клиент. <a href="https://tanstack.com/query/latest">TanStack Query</a> синхронизирует серверный и клиентский рендеринг.</li></ul><p>Но есть и ложка дегтя. Отладка усложняется, если что-то сломается внутри обертки — придётся копать глубже. Возникает зависимость от библиотек: <a href="https://github.com/typestack/class-transformer">class-transformer</a>, axios и сам <a href="https://tanstack.com/query/latest">TanStack Query</a> становятся обязательными.</p><p>Однако игра стоит свеч. Потому что время, сэкономленное на рутине, можно потратить на то, что действительно важно —  фичи, которые понравятся пользователям, а не бесконечные правки API-вызовов.</p><h4>Сравнительные примеры</h4><p>GET /products — Список продуктов</p><p>GET /products/:id — Один продукт по id</p><p>POST /products — Создание продукта</p><p>PUT /products/:id — Обновление продукта по id</p><p>DELETE /products/:id — Удаление продукта по id</p><h4>Как это выглядит в обертке</h4><h4>Все свойства и возвращаемые хуки и конфиги из фабрики:</h4><h4>Пример использования в компонентах:</h4><h4>Использование конфигов:</h4><h4>Для сравнения с классическим решением:</h4><figure><img src="https://media.tproger.ru/user-uploads/115291/2025-05-22/efa40892-0692-4a19-9796-8f993267a22d.png" alt="Сравнение обычного использования и фабрики" /><figcaption>Сравнение обычного использования и фабрики</figcaption></figure><h2>Когда стоит переходить на обертку?</h2><p>Не каждый проект нуждается в таком подходе к API. Если у вас два-три endpoint’а и они никогда не меняются — возможно, обертка будет избыточной. Но представьте стартап, где каждый месяц добавляются новые сущности: сначала товары, потом отзывы, потом промокоды, рекомендации, аналитика.</p><p>Вот где система раскрывается на полную! Новая сущность? Пять минут на добавление — и готовы все CRUD-операции. Изменился бэкенд? Правим в одном месте — и все работает.  Пришел новый разработчик? Он не тратит неделю на изучение особенностей API.</p><p>Правда, если бэкенд живет в мире хаотичных endpoint’ов (например, GET /fetch_items, но DELETE /removeProduct), обертка не спасет.</p><h4>Но как навести порядок?</h4><p>Главный секрет — общаться. Не ждать, пока API сломается, а сразу договориться:</p><ul><li>Какие будут названия полей (created_at vs createdAt);</li><li>Как структурированы ошибки;</li><li>Когда и как можно менять контракт.</li></ul><p>Как сказал один разработчик: «фронтенд и бэкенд — как соседи по коммуналке. Можно ругаться из-за бардака на кухне, но лучше сесть и написать правила совместного проживания».</p><p>А напоследок —  график, для закрепления разницы между работой с оберткой и без нее.</p><figure><img src="https://media.tproger.ru/user-uploads/115291/2025-05-22/5f23aca4-8353-4ff4-8923-f24685395bb2.png" alt="График сравнительного примера" /><figcaption>График сравнительного примера</figcaption></figure>]]></content:encoded>
    </item>
    <item>
      <title>Настраиваем паука для сбора данных: как работает фреймворк Scrapy</title>
      <link>https://tproger.ru/articles/nastraivaem-pauka-dlya-sbora-dannyh--kak-rabotaet-frejmvork-scrapy</link>
      <comments>https://tproger.ru/articles/nastraivaem-pauka-dlya-sbora-dannyh--kak-rabotaet-frejmvork-scrapy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ekaterina Davidova]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/nastraivaem-pauka-dlya-sbora-dannyh--kak-rabotaet-frejmvork-scrapy</guid>
      <description><![CDATA[<p>В Точке мы обучаем наших AI-ассистентов, а для этого нужно много данных. В статье расскажу, как быстро собрать информацию практически с любого сайта при помощи фреймворка Scrapy. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/nastraivaem-pauka-dlya-sbora-dannyh--kak-rabotaet-frejmvork-scrapy">Настраиваем паука для сбора данных: как работает фреймворк Scrapy</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[DPI]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 07 Apr 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В Точке мы обучаем наших AI-ассистентов, а для этого нужно много данных. В статье расскажу, как быстро собрать информацию практически с любого сайта при помощи фреймворка Scrapy.</p><h2>Зачем компании собирают данные</h2><p>Сегодня в интернете более 1 миллиарда сайтов. На великом и ужасном реддите каждый час появляется более 50 000 новых публикаций. На Github уже опубликовано более 300 млн публичных репозиториев. Всё это — открытые данные, которые можно использовать и, главное — собирать. Разумеется, перед этим проверить условия использования сайта, потому что некоторые из них могут запрещать сбор данных.</p><p><b>Зачем это нужно компаниям:</b></p><ul><li><b>Анализ рынка:</b> для ритейла это возможность изучить клиентов и конкурентов.</li><li><b>Мониторинг сайтов вендоров ПО: </b>некоторые компании выкладывают уязвимости в своих продуктах и делятся возможными решениями.</li><li><b>Создание продукта: </b>собранные данные можно обогатить, прикрутить красивый интерфейс, умный поиск и предложить пользователю новое приложение, типа 2GIS.</li><li><b>Развитие LLM: </b>например, Google в 2024 году заключил контракт с Reddit на сбор данных. Open AI тоже часто говорят о том, что обучают свою модель на открытых источниках, а в ближайшее время хотят подключить ещё и транскрибации с YouTube.</li></ul><p>Как вы поняли, в интернете очень много данных. И если мы хотим их собрать, то нам нужен подходящий инструмент.</p><h2>Что такое Scrapy</h2><p>Это высокоуровневый фреймворк на Python для краулинга и скреппинга сайтов. На GitHub у него больше 53 тысяч звёздочек, 10,6 тысяч форков и много глазиков. А ещё он занимает первое место по тегам #crawling и #scraping.</p><figure><img src="https://media.tproger.ru/user-uploads/108715/2025-04-06/e72840e2-833f-411b-bb5f-0ade0d6ea7f7.png" alt="" /></figure><p><b>Есть много причин, почему Scrapy так популярен: </b></p><ul><li>Это фреймворк с готовой архитектурой — там много инструментов, доступных из коробки, которые можно настроить и использовать.</li><li>Он асинхронный — чаще возникает задача замедлить его, чем ускорить.</li><li>У него простые настройки — нужно всего раз подумать над архитектурой, а добавление новых источников будет занимать минимум времени.</li><li>Scrapy удобно дебажить в любой момент, начиная от загрузки страницы и заканчивая сохранением данных в базе.</li><li>Есть продуманные селекторы, доступны CSS, Xpath. Их можно комбинировать или выбрать что-то одно.</li><li>Большое комьюнити и обновляемая документация. Ответы на большинство вопросов можно легко найти в сети.</li></ul><p>Scrapy точно подойдёт вам, если во всех ваших источниках одинаковый формат данных и вы можете унифицировать их обработку и сохранение. Но всё-таки его нельзя назвать универсальным инструментом.</p><p><b>Scrapy будет не лучшим выбором, если: </b></p><ul><li>Нужно собрать малый объем данных или собрать их нужно всего один раз.</li><li>Вам нужно отдать просто сырые html или json, а не парсить и преобразовывать данные.</li><li>Среди источников нет общей структуры данных.</li></ul><p>Во всех этих случаях мы можем использовать Scrapy, но, скорее всего, он будет излишним.</p><h2>Как работает Scrapy</h2><p>После того, как вы установили Scrapy в виртуальное окружение ( '' pip instal scrapy' ) и создали новый проект ( ' scrapy startprogect scraper '' ), вам необходимо написать своего первого «паука».</p><p>В Scrapy используется класс spider — он определяет, как мы будем извлекать данные из сайтов. Допустим, нам нужно собрать информацию с одностраничного сайта. Создаём класс TestSpider, наследуемся от scrapy.Spider, добавляем атрибут name с уникальным именем и start_urls, где укажем страницы, с которых нужно начать поиск. После этого переопределим метод parse.</p><p>Parse является дефолтным для обработки ответов. Если вы сделаете request и не укажете функцию, которая должна его обработать, то ответ от запроса придёт в метод parse. Поэтому его, как минимум, нужно переопределить и назначить логику.</p><p>Допустим, нас интересует информация о компании — название и описание. Можем создать объект данных с двумя элементами — title и content, и с помощью двух xpath селекторов забрать со страницы заголовок и описание.</p><p>В конце передаём этот объект данных для последующей обработки в ядро. Это всё, что нужно, чтобы начать парсинг на Scrapy.</p><h2>Обработка данных в Scrapy</h2><p>Дальше в ход вступает PipeLine. Он отвечает за обработку данных, валидацию или сохранение. В Scrapy есть пайплайны, готовые из коробки, но вы также можете написать их самостоятельно.</p><p>В ValidatePipeline мы проверяем объект данных на наличие title, а в SavePipeline — сохраняем объект в качестве json.</p><p>Здесь я просто показал, как можно создать пайплайн самостоятельно. Но имейте в виду, что это не очень отказоустойчивый код, поэтому в проде так делать не стоит.</p><h2>Зачем нужен Middleware</h2><p>Middleware очень похож на PipeLine, только он обрабатывает не объекты данных, а запросы и ответы от сайта.</p><p>В Scrapy есть несколько разных middleware:</p><ul><li><b>scheduler middleware:</b> помещает запросы в очередь и извлекает их для обработки.</li><li><b>spider middleware: </b>управляет данными между пауком и ядром.</li><li><b>downloader middleware: </b>управляет данными между ядром и загрузчиком.</li></ul><p>Получается такая схема работы компонентов Scrapy:</p><p><i>Запрос: Spider → Spider Middleware → Engine → Scheduler Middleware → Scheduler → Engine → Downloader Middleware → Downloader → Server (сайт)</i></p><p><i>Ответ: Server → Downloader → Downloader Middleware → Engine → Spider Middleware → Spider → Item Pipeline → Storage (хранилище данных)</i></p><p>Скорее всего, в первую очередь вы будете настраивать downloader middleware, поэтому разберём его подробнее.</p><p>Ниже продемонстрировал два примера, как можно написать свой Middleware. В RandomProxyMiddleware мы обрабатываем все запросы, которые будет отсылать наш паук с помощью метода process_request (добавляем рандомную прокси к каждому реквесту), а в CheckCaptchaMiddleware — обрабатываем все ответы с помощью метода process_response (проверяем ответ от сайта, ищем в нём слово captcha).</p><p>Итак, мы написали Pipeline и Middlewares. Дальше нужно указать, как мы будем их использовать. Для этого запишите их в файле <a href="http://settings.py/">settings.py</a>, где находятся настройки проекта.</p><p>Начнём с пайплайнов. Цифра справа — это порядковый номер выполнения. То есть первым будет ValidatePipeLine, а вторым сработает SavePipeline. Обычно цифры указываются от 0 до 1000. И в случае с пайплайнами чем ниже цифра, тем раньше сработает пайплайн.</p><p>В случае с middleware картина такая же, но логика немного иная.</p><p>Каждый middleware может обрабатывать как request, так и response. При этом middleware стоит посередине между ядром, который отправляет запросы, и загрузчиком. Если ваша middleware обрабатывает запросы, то сработает первой та, что указана с меньшей цифрой, потому что она ближе к ядру. А если middleware обрабатывает ответы, то первой будет та, у которой цифра больше, потому что она дальше от ядра и ближе к загрузчику.</p><figure><img src="https://media.tproger.ru/user-uploads/108715/2025-04-06/db359adf-e3fd-40c8-81e5-5c0d9658bd0a.png" alt="" /></figure><p>Об этот нюанс часто спотыкаются новички, хотя, скорее всего, он прописан в документации.</p><h2>Пример, как использовать Scrapy</h2><p>Рассмотрим, как с помощью одного селектора собрать сайт любой вложенности и архитектуры.</p><p>Для начала создаём класс паука, наследуемся от scrapy.Spider, указываем name, start_urls и атрибут allowed_domains — он необязательный, но в данном случае без него не обойтись. В нём мы укажем список хостов, на которые разрешаем ходить нашему пауку, чтобы он не начал собирать другие сайты.</p><p>Дальше переопределяем метод parse и, когда к нам приходит ответ от сайта, находим все ссылки. И это и есть тот единственный xpath селектор, который поможет обойти весь сайт и собрать страницы.</p><p>Все ссылки помещаем в переменную url в качестве списка, а потом этот список передаём в функцию follow_all объекта response.</p><p>Чтобы дописать сохранение, просто передаём объект response вглубь ядра Scrapy, где напишем какой-то нехитрый пайплайн и будем сохранять html-страницы. Так можно собрать абсолютно любой сайт, просто подставьте ссылку на него в start_urls.</p><p>Важный нюанс: под капотом follow_all сделает запросы к сайту по всем ссылкам, которые мы нашли на странице. И поскольку в follow all мы не указываем определённый метод в параметре callback, то все ответы придут сюда же в метод parse (потому что он дефолтный в Scrapy). Эта логика будет повторяться на каждой странице.</p><p>Ещё в Scrapy есть внутренний фильтр, поэтому если паук соберёт дубликаты, то автоматически зафильтрует их и не будет проходить по ссылкам дважды.</p><h2>Немного итогов</h2><p>Scrapy — это большой, сложный, но очень хороший фреймворк, как Django в веб-разработке. Он предлагает большой выбор готовых инструментов для сбора и обработки данных, а также, поддерживает асинхронное выполнение задач, что ускоряет процесс парсинга.</p><p>Scrapy может показаться трудным для новичков, но у него есть богатая документация и примеры, поэтому при желании в нём нетрудно разобраться.</p>]]></content:encoded>
    </item>
    <item>
      <title>Семь API, которые сократят вам недели разработки</title>
      <link>https://tproger.ru/articles/10-api--kotorye-sokratyat-vam-nedeli-razrabotki</link>
      <comments>https://tproger.ru/articles/10-api--kotorye-sokratyat-vam-nedeli-razrabotki?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/10-api--kotorye-sokratyat-vam-nedeli-razrabotki</guid>
      <description><![CDATA[<p>В этом списке — семь мощных API, которые помогут вам ускорить разработку, автоматизировать рутинные задачи и без лишних усилий добавить крутые функции. От баз данных книг до парсинга сайтов и анализа пользовательских данных</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/10-api--kotorye-sokratyat-vam-nedeli-razrabotki">Семь API, которые сократят вам недели разработки</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 04 Apr 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Представьте, что вам нужно встроить в своё приложение поиск книг, анализ геоданных или генерацию случайных пользователей. Вы могли бы писать код с нуля, разбираться с источниками, тестировать и отлаживать… или просто воспользоваться готовыми API, которые сделают всю работу за вас. Сегодня о них и поговорим.</p><h2>Shodan API: Поиск уязвимостей в интернете за минуты</h2><p><a href="https://developer.shodan.io/">Shodan</a> — поисковая система для интернет-устройств. В отличие от Google, который индексирует веб-страницы, Shodan сканирует открытые порты, сервисы и устройства, подключённые к интернету. Это делает его мощным инструментом для исследователей безопасности, разработчиков и системных администраторов.</p><p>Shodan API позволяет автоматизировать поиск уязвимых серверов, камер наблюдения, баз данных и других интернет-ресурсов. Может анализировать их конфигурации и даже отслеживать инциденты безопасности в реальном времени.</p><h2>Как Shodan API экономит время разработчикам?</h2><p>Ручной аудит серверов и интернет-устройств может занять недели, а то и месяцы, но Shodan API позволяет:</p><ul><li>Быстро находить уязвимые устройства и сервисы</li><li>Проверять, какие технологии и версии ПО используются на серверах</li><li>Получать статистику по открытым портам, SSL-сертификатам и угрозам</li><li>Отслеживать новые уязвимости в реальном времени</li></ul><p>Для DevOps, SOC-аналитиков и специалистов по информационной безопасности это возможность автоматизировать рутинные проверки и защитить инфраструктуру от потенциальных атак.</p><h2>Как использовать Shodan API?</h2><p>Shodan API предоставляет удобные методы для работы с данными через REST-запросы. Рассмотрим основные возможности.</p><h4>Поиск открытых сервисов и устройств</h4><p>Shodan позволяет находить устройства, доступные по определённым портам, IP-адресам или географическим координатам. Например, запрос всех открытых баз данных MongoDB:</p><p>Ответ покажет список IP-адресов, страну расположения серверов и используемые версии ПО.</p><h4>Получение информации об IP-адресе</h4><p>Допустим, вы хотите узнать, какие сервисы запущены на конкретном IP. Используем команду:</p><p>Ответ будет содержать список открытых портов, заголовки HTTP-ответов и используемые технологии.</p><h4>Поиск устройств по версии ПО</h4><p>Чтобы найти все серверы с устаревшей версией OpenSSH, можно выполнить запрос:</p><p>Это полезно для поиска серверов, подверженных атакам из-за старых версий ПО.</p><p>Важно понимать, что Shodan не предназначен для хакерских атак. Использование API для несанкционированного сканирования чужих серверов может быть незаконным. Поэтому рекомендуется работать только с теми системами, на которые у вас есть разрешение.</p><h2>Abstract API: Быстрая проверка IP, валидация email и работа с геоданными</h2><p><a href="https://www.abstractapi.com/">Abstract API</a> — сервис, предлагающий набор API для работы с IP-адресами, валидацией email, проверкой телефона, распознаванием валют и многим другим. Это универсальный инструмент для веб-разработчиков, аналитиков и специалистов по безопасности.</p><h3>Как Abstract API экономит время разработчикам?</h3><p>Вместо того чтобы искать разные API для работы с геоданными, email-валидацией и IP-адресами, можно использовать Abstract API. Это экономит часы на интеграцию и позволяет быстро решать задачи, такие как:</p><ul><li>Определение страны и города пользователя по IP</li></ul><ul><li>Проверка подлинности email перед регистрацией</li></ul><ul><li>Конвертация валют в реальном времени</li></ul><ul><li>Валидация телефонных номеров</li></ul><p>Abstract API помогает автоматически фильтровать спам-регистрации, защищать системы от ботов и улучшать пользовательский опыт.</p><h3>Как использовать Abstract API?</h3><p>API работает через REST-запросы и доступно для бесплатного использования с ограничениями.</p><h4>Определение геолокации по IP</h4><p>Можно быстро определить страну, город и провайдера пользователя:</p><h4>Валидация email-адреса</h4><p>Проверяем, является ли email настоящим, одноразовым или корпоративным:</p><p>Что нужно помнить? Бесплатная версия ограничена числом запросов в месяц. А данные по IP-геолокации иногда могут быть неточными (зависит от провайдера).</p><h2>Zyte API: Интеллектуальный ротационный прокси для веб-скрейпинга без блокировок</h2><p><a href="https://www.zyte.com/smart-proxy-manager/">Zyte API</a> — мощный API для веб-скрейпинга, который не только обходит блокировки и капчи, но и автоматически структурирует полученные данные. Он объединяет в себе прокси-серверы, обработку JavaScript-страниц и инструменты парсинга, что делает его одним из самых удобных решений для сбора данных с веб-ресурсов.</p><h2>Как Zyte API экономит время?</h2><p>Вместо того чтобы вручную разрабатывать сложные парсеры и бороться с защитами сайтов, Zyte API позволяет получить уже готовые структурированные данные:</p><ul><li>Автоматическая обработка JavaScript-страниц (открывает динамически загружаемые сайты, как Selenium).</li></ul><ul><li>Обход капч и блокировок (использует интеллектуальные прокси).</li></ul><ul><li>Автоматическое структурирование данных (не просто HTML, а уже готовая JSON-структура).</li></ul><ul><li>Интеграция с Python и REST API (работает с любыми языками программирования).</li></ul><p>API идеально подходит для разработчиков, аналитиков, маркетологов и исследователей данных.</p><h2>Как использовать Zyte API?</h2><p>Он работает как обычный прокси: достаточно настроить его в коде, и все запросы к сайтам будут проходить через интеллектуальную систему ротации IP.</p><h4>Использование Zyte в curl</h4><p>Допустим, нужно скачать HTML-страницу сайта example.com:</p><p>Что нам ответят:</p><h4>Интеграция с Python</h4><p>Для начала нужно установить клиент:</p><p>Код для парсинга и получения данных:</p><h4>Автоматический парсинг данных</h4><p>Zyte API умеет не только загружать HTML, но и автоматически извлекать полезные данные. Например, спарсить цену, название и описание кроссовок в интернет-магазине (ну или любого другого товара).</p><p>Из минусов — нет бесплатного доступа (лишь пробный период). Также некоторые страницы требуют больше времени для обхода ограничений (может понадобиться доп.настройка).</p><h2>Common Crawl API: Бесплатная база данных для веб-скрейпинга и анализа интернета</h2><p><a href="https://commoncrawl.org/">Common Crawl</a> — не просто API, а целый архив интернета, содержащий огромные объемы веб-данных, собранных с 2008 года. В отличие от стандартных API для веб-скрейпинга, Common Crawl предоставляет доступ к готовым копиям страниц, что значительно ускоряет анализ веб-контента и снижает нагрузку на исходные сайты.</p><h3>Как Common Crawl API экономит время?</h3><p>Вместо того чтобы разрабатывать сложные парсеры и загружать миллионы страниц вручную, Common Crawl позволяет быстро находить нужную информацию в готовых архивах:</p><ul><li>Бесплатный доступ к огромной базе веб-страниц (петабайты данных, обновляемых ежемесячно).</li></ul><ul><li>Исторические данные (можно анализировать, как изменялся контент сайтов за годы).</li></ul><ul><li>Отсутствие блокировок и капч (данные уже собраны, вам не нужно бороться с защитами сайтов).</li></ul><ul><li>Возможность массового анализа веба (идеально для NLP, машинного обучения и SEO-исследований).</li></ul><p>API и данные Common Crawl полезны для исследователей, дата-аналитиков, SEO-специалистов и разработчиков.</p><h3>Как использовать Common Crawl API?</h3><p>Common Crawl предоставляет данные в формате WARC (архивные копии страниц) и WET (чистый текст без HTML). Доступ осуществляется через Amazon S3, но также можно использовать API Common Crawl Index для поиска нужных URL.</p><h4>Поиск веб-страниц через API</h4><p>Допустим, нам нужны все страницы, содержащие example.com:</p><p>Вот такой ответ может быть:</p><h4>Получение текста страницы из архива</h4><p>После получения ссылки на WARC-файл можно скачать его и распаковать:</p><p>Ну и затем извлечь текст:</p><h4>Анализ больших объемов данных с AWS</h4><p>Если вам нужны миллионы страниц, можно использовать AWS Athena для обработки данных прямо в облаке.</p><p>Пример SQL-запроса в AWS Athena для поиска страниц с «machine learning»:</p><p>Важно отметить, что данные предоставляются в сыром виде и их нужно дополнительно обрабатывать. Плюс нет гарантии, что конкретная страница будет в архиве.</p><h2>GitHub API: автоматизация работы с репозиториями, пользователями и кодом</h2><p><a href="https://docs.github.com/en/rest">GitHub API</a> — интерфейс для взаимодействия с кодом, репозиториями, пользователями и организациями на платформе GitHub. Он позволяет автоматизировать задачи, получать аналитику, управлять репозиториями, отслеживать запросы на вытягивание, коммиты и многое другое.</p><h3>Как GitHub API экономит время?</h3><p>Вместо ручного управления репозиториями и кодом через интерфейс GitHub можно автоматизировать эти процессы с помощью API:</p><ul><li>Автоматизация деплоя и CI/CD (создание и управление GitHub Actions).</li></ul><ul><li>Мониторинг активности в репозиториях (новые коммиты, запросы на вытягивание, проблемы).</li></ul><ul><li>Управление пользователями и организациями (добавление разработчиков, управление доступом).</li></ul><ul><li>Анализ кода и метрик (подсчёт строк кода, статистика участников).</li></ul><ul><li>Поиск по репозиториям и файлам (быстрое извлечение нужной информации).</li></ul><p>GitHub API полезен для DevOps-инженеров, разработчиков, владельцев проектов и аналитиков.</p><h3>Как использовать GitHub API?</h3><p>GitHub API работает через REST-запросы и возвращает данные в формате JSON. Для авторизации можно использовать токен личного доступа (PAT) или OAuth.</p><h4>Получение информации о пользователе GitHub</h4><p>Допустим, мы хотим узнать данные о пользователе natasharostova:</p><p>Как нам могут ответить:</p><h4>Создание нового репозитория через API</h4><p>После выполнения запроса появится новый репозиторий new-repo.</p><h4>Поиск репозиториев по ключевому слову</h4><p>Допустим, мы хотим найти репозитории, содержащие код на Python, связанный с машинным обучением:</p><p>Нужно понимать, что есть ограничение в 5000 API-запросов в час для авторизованных пользователей. Для некоторых функций требуется версия GitHub Enterprise.</p><h2>MuleSoft API: Универсальный коннектор для интеграции сервисов</h2><p><a href="https://openlibrary.org/developers/api"></a><a href="https://www.mulesoft.com/">MuleSoft API</a> — платформа для интеграции различных систем, сервисов и приложений. Она позволяет соединять облачные и локальные системы, автоматизировать обмен данными и управлять API. MuleSoft широко используется в корпоративных средах для построения сложных интеграционных решений.</p><h3>Как MuleSoft API экономит время?</h3><p>Вместо того чтобы разрабатывать интеграции с нуля, MuleSoft API предлагает готовые коннекторы, которые позволяют:</p><ul><li>Интегрировать разные системы (CRM, ERP, базы данных, облачные сервисы) без сложного кодинга.</li></ul><ul><li>Автоматизировать обмен данными между приложениями (например, между Salesforce и SAP).</li></ul><ul><li>Обеспечивать безопасность API с помощью встроенных инструментов управления доступом.</li></ul><ul><li>Создавать микросервисную архитектуру, где API работают как модули.</li></ul><p>API полезен для DevOps-инженеров, архитекторов ПО, разработчиков корпоративных решений и интеграторов.</p><h3>Как использовать MuleSoft API?</h3><p>MuleSoft поддерживает REST и SOAP API, а также интеграцию через готовые коннекторы.</p><h4>Создание API с помощью Anypoint Platform</h4><p>Anypoint Platform — облачная среда MuleSoft, в которой можно управлять API.</p><p>Пример запроса к API через MuleSoft:</p><h4>Подключение к базе данных через DataWeave</h4><p>DataWeave — это язык MuleSoft для трансформации данных. Он позволяет легко преобразовываться в нужные форматы.</p><p><i>Это правило конвертирует XML-ответ базы данных в JSON.</i></p><p>Важно помнить, что бесплатные возможности платформы ограничены. Также сервис требует обучения: для работы с DataWeave и Anypoint Platform нужно разбираться в интеграции API.</p><h2>JSONPlaceholder API: бесплатный фиктивный REST API для тестирования и создания прототипов</h2><p><a href="https://jsonplaceholder.typicode.com/">JSONPlaceholder API</a> — бесплатный REST API, предназначенный для тестирования, создания прототипов и обучения разработчиков. Он предоставляет фиктивные данные (пользователей, публикаций, комментариев и т. д.), которые можно использовать при разработке клиентских и серверных приложений без необходимости развёртывать собственный бэкенд.</p><h3>Как JSONPlaceholder API экономит время?</h3><p>Разработчикам часто нужно тестировать фронтенд или отлаживать API-запросы, но не всегда есть готовый бэкенд. JSONPlaceholder API решает эту проблему:</p><ul><li>Позволяет мгновенно получать тестовые данные без развертывания сервера.</li></ul><ul><li>Не требует регистрации или API-ключа.</li></ul><ul><li>Поддерживает стандартные HTTP-методы (GET, POST, PUT, DELETE).</li></ul><ul><li>Полностью совместим с популярными библиотеками и фреймворками (Axios, Fetch API, jQuery и др.).</li></ul><p>API полезен для фронтенд-разработчиков, тестировщиков, студентов и преподавателей программирования.</p><h3>Как использовать JSONPlaceholder API?</h3><p>JSONPlaceholder предоставляет несколько ресурсов, которые можно запрашивать с помощью HTTP-запросов.</p><h4>Получение списка пользователей</h4><p>Простейший GET-запрос возвращает список тестовых пользователей:</p><h4>Получение списка постов</h4><p>Можно запросить список фиктивных публикаций:</p><h4>Добавление нового поста</h4><p>Можно отправить POST-запрос, чтобы имитировать создание записи:</p><h4>Обновление записи</h4><p>Для изменения существующей записи можно использовать PUT-запрос:</p><p>Что нужно помнить? Данные статичны — они не сохраняются между запросами. Запросы POST, PUT и DELETE не изменяют реальные данные. А само API предназначено только для тестирования, а не для использования в рабочей среде.</p>]]></content:encoded>
    </item>
    <item>
      <title>Топ 15 расширений Google Chrome для аналитиков данных</title>
      <link>https://tproger.ru/articles/top-15-raswirenij-google-chrome-dlya-analitikov-dannyh</link>
      <comments>https://tproger.ru/articles/top-15-raswirenij-google-chrome-dlya-analitikov-dannyh?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/top-15-raswirenij-google-chrome-dlya-analitikov-dannyh</guid>
      <description><![CDATA[<p>Узнайте о 15 расширениях Google Chrome для аналитиков данных. Парсинг, визуализация, автоматизация и удобные инструменты для работы с данными — полный обзор с примерами использования.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/top-15-raswirenij-google-chrome-dlya-analitikov-dannyh">Топ 15 расширений Google Chrome для аналитиков данных</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Google Chrome]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Визуализация]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Google Analytics]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 02 Mar 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Работа аналитика данных включает парсинг информации, анализ пользовательского поведения, работу с визуализацией и оптимизацию процессов. Google Chrome предлагает множество расширений, которые помогают решать эти задачи быстрее и эффективнее.</p><p>Мы собрали <b>15</b> <b>инструментов</b>, которые пригодятся аналитикам данных, и разобрали их функционал.</p><h2>Data Scraper —  извлечение данных с веб-страниц</h2><p><a href="https://chromewebstore.google.com/detail/data-scraper-easy-web-scr/nndknepjnldbdbepjfgmncbggmopgden">Ссылка на расширение </a></p><p><b>Для чего?</b> Автоматический сбор таблиц, списков и других данных с сайтов. Он загружает данные в CSV, Excel или Google Sheets без необходимости программирования.</p><p><b>Пример использования.</b> Вы анализируете цены конкурентов в интернет-магазинах и хотите собрать данные о стоимости товаров. Data Scraper автоматически извлекает нужные элементы и экспортирует их в таблицу.</p><p>✅ Плюсы: удобство, простота настройки, экспорт в популярные форматы.</p><p>❌ Минусы: ограниченная бесплатная версия, не работает на защищенных сайтах.</p><h2>Web Scraper — мощный инструмент для автоматизированного сбора данных</h2><p><a href="https://chromewebstore.google.com/detail/web-scraper/dogiinkejekngjnphjklkdohanocpnfj?hl=ru">Ссылка на расширение</a></p><p><b>Для чего?</b> Глубокий парсинг с поддержкой вложенных страниц. Инструмент настраивает сценарии обхода динамических сайтов и сбора их данных.</p><p><b>Пример использования. </b>Вы анализируете вакансии на сайтах работодателей и хотите собрать данные по зарплатам, названиям должностей и требованиям.</p><p>✅ Плюсы: гибкость, автоматический обход страниц.</p><p>❌ Минусы: требует понимания HTML-структуры сайтов.</p><h2>Awesome Table —  превращение данных в интерактивные отчёты</h2><p><a href="https://workspace.google.com/marketplace/app/awesome_table/56088344336">Ссылка на расширение</a></p><p><b>Для чего?</b> Помощь в визуализации данных в Google Sheets. Создает наглядные дашборды, которые можно встроить в сайт или презентацию.</p><p><b>Пример использования.</b> У вас есть список клиентов с продажами, и вы хотите создать интерактивный отчет с фильтрацией по странам, категориям и датам.</p><p>✅ Плюсы: легкость настройки, хорошая интеграция с Google.</p><p>❌ Минусы: ограничения в бесплатной версии.</p><h2>Octoparse —  мощный инструмент для парсинга данных</h2><p><a href="https://chromewebstore.google.com/detail/octoparse-voc-ai-review-r/dcejniggmfiedegekbcindccneeegeoi">Ссылка на расширение</a></p><p><b>Для чего?</b> Автоматизирует сбор данных с веб-страниц без программирования. Позволяет извлекать таблицы, списки товаров, контактные данные, и даже имитировать действия пользователя на сайте.</p><p><b>Пример использования.</b> Допустим, вам нужно собрать список всех статей по определённой тематике с крупного новостного портала. Octoparse создаст сценарий, который будет автоматически переходить по страницам, извлекать заголовки, даты публикации и ссылки, а затем экспортировать данные в CSV или Excel.</p><p>✅ Плюсы: Не требует знаний программирования; поддерживает сложные сценарии парсинга (например, клик по кнопке «Показать ещё»).</p><p>❌ Минусы: Ограниченный функционал в бесплатной версии; может не работать с сайтами, защищёнными от ботов (например, Cloudflare)</p><h2>Selenium IDE — автоматизация тестирования прямо в браузере</h2><p><a href="https://chromewebstore.google.com/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd">Ссылка на расширение</a></p><p>Для чего? Записывает и выполняет тесты веб-приложений без написания кода. Позволяет тестировать формы, кнопки, навигацию и другие элементы сайтов.</p><p>Пример использования. Вы разработчик или аналитик, которому нужно проверить, как работает новый функционал на сайте. Вместо ручного тестирования Selenium IDE записывает ваши действия (ввод в форму, клик по кнопке) и воспроизводит их автоматически.</p><p>✅ Плюсы: Возможность экспорта сценариев в разные языки (Python, Java, JavaScript).</p><p>❌ Минусы: Ограниченные возможности по сравнению с полноценным Selenium WebDriver.</p><h2>Google Analytics Debugger —  отладка событий в GA</h2><p><a href="https://chromewebstore.google.com/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna">Ссылка на расширение</a></p><p><b>Для чего?</b> Проверка корректности передачи данных в Google Analytics. Показывает, какие события отправляются в аналитику.</p><p><b>Пример использования.</b> Если в аналитике не отображаются клики по кнопке «Купить», Debugger поможет понять, передаются ли данные в систему.</p><p>✅ Плюсы: подробные логи, быстрая диагностика проблем.</p><p>❌ Минусы: поддерживает только Universal Analytics, не GA4.</p><h2>DataLayer Checker —  проверка передачи данных</h2><p><a href="https://chromewebstore.google.com/detail/datalayer-checker/ffljdddodmkedhkcjhpmdajhjdbkogke">Ссылка на расширение</a></p><p><b>Для чего? </b>диагностика переменных DataLayer в GTM. Показывает, какие данные передаются на сайт.</p><p><b>Пример использования.</b> Хотите убедиться, что в аналитику передаются все параметры заказа? DataLayer Checker покажет их в реальном времени.</p><p>✅ Плюсы: помогает в настройке e-commerce аналитики.</p><p>❌ Минусы: сложен для новичков.</p><h2>Tableau Chrome Extension —  удобная работа с дашбордами</h2><p><a href="https://chromewebstore.google.com/detail/tableau-chrome-extension/ocnnlomigllkiegmgkbodenbgpahbogc">Ссылка на расширение</a></p><p><b>Для чего? </b>Облегчает доступ к дашбордам Tableau. Загружает отчеты без необходимости заходить на сайт.</p><p><b>Пример использования.</b> Вы работаете в команде аналитиков и хотите быстро проверять дашборды Tableau прямо из браузера.</p><p>✅ Плюсы: ускоряет доступ к данным.</p><p>❌ Минусы: требует подписки на Tableau.</p><h2>Block Yourself from Analytics — исключение собственного трафика</h2><p><a href="https://chromewebstore.google.com/detail/block-yourself-from-analy/fadgflmigmogfionelcpalhohefbnehm">Ссылка на расширение</a></p><p><b>Для чего? </b>Чтобы не учитывать свои визиты в Google Analytics.</p><p><b>Пример использования. </b>Вы администратор сайта и не хотите искажать данные в GA своими посещениями.</p><p>✅ Плюсы: легко включается и выключается.</p><p>❌ Минусы: работает только в Chrome.</p><h2>Table Capture —  копирование таблиц с сайтов</h2><p><a href="https://chromewebstore.google.com/detail/table-capture/iebpjdmgckacbodjpijphcplhebcmeop">Ссылка на расширение</a></p><p><b>Для чего?</b> Экспорт таблиц с сайтов в Excel и Google Sheets.</p><p><b>Пример использования. </b>Вам нужно быстро перенести данные текстовой таблицы с веб-страницы в Google Sheets.</p><p>✅ Плюсы: это, как минимум, удобно.</p><p>❌ Минусы: не всегда корректно распознает сложные таблицы.</p><h2>JSONView —  удобное представление JSON-данных</h2><p><a href="https://chromewebstore.google.com/detail/jsonview/gmegofmjomhknnokphhckolhcffdaihd?hl=ru">Ссылка на расширение</a></p><p><b>Для чего? </b>Форматирование JSON-файлов в читаемый вид.</p><p><b>Пример использования.</b> Вы работаете с API и хотите быстро понять структуру JSON-ответов.</p><p>✅ Плюсы: цветовая подсветка.</p><p>❌ Минусы: не редактирует JSON.</p><h2>Scraper —  быстрый экспорт данных с сайтов</h2><p><a href="https://chromewebstore.google.com/detail/scraper/mbigbapnjcgaffohmbkdlecaccepngjd">Ссылка на расширение</a></p><p><b>Для чего? </b>Извлекает текстовые и табличные данные с веб-страниц без сложных настроек.</p><p><b>Пример использования. </b>Вы анализируете список товаров на маркетплейсе и хотите собрать данные о ценах и наличии.</p><p>✅ Плюсы: прост в использовании, есть интеграция с Google Sheets.</p><p>❌ Минусы: ограниченный функционал по сравнению с Web Scraper.</p><h2>Wappalyzer — определение технологий сайтов</h2><p><a href="https://chromewebstore.google.com/detail/wappalyzer-technology-pro/gppongmhjkpfnbhagpmjfkannfbllamg">Ссылка на расширение</a></p><p><b>Для чего?</b> Показывает, какие CMS, языки программирования, аналитические сервисы и рекламные сети использует сайт. Полезен для конкурентного анализа и технических исследований.</p><p><b>Пример использования.</b> Вы изучаете сайты конкурентов и хотите понять, какие технологии они применяют (используют ли Google Tag Manager и т.д.).</p><p>✅ Плюсы: удобный интерфейс, быстрый анализ.</p><p>❌ Минусы: иногда пропускает редкие технологии.</p><h2>OpenLink Structured Data Sniffer — анализ структурированных данных</h2><p><a href="https://chromewebstore.google.com/detail/openlink-structured-data/egdaiaihbdoiibopledjahjaihbmjhdj?hl=en">Ссылка на расширение</a></p><p><b>Для чего?</b> Извлекает и анализирует JSON-LD, RDF на сайтах. Помогает проверить корректность разметки страниц для поисковых систем.</p><p><b>Пример использования.</b> Вы работаете с SEO и хотите проверить, правильно ли настроены schema.org-разметки на сайте клиента.</p><p>✅ Плюсы: детализированный анализ.</p><p>❌ Минусы: требует знаний о структурированных данных.</p><h2>Tag Assistant — анализ работы тегов Google</h2><p><a href="https://chromewebstore.google.com/detail/tag-assistant/kejbdjndbnbjgmefkgdddjlbokphdefk">Ссылка на расширение</a></p><p><b>Для чего?</b> Проверка корректности работы Google Tag Manager, Analytics и Ads. Анализирует теги, выявляет ошибки в их настройке.</p><p><b>Пример использования.</b> Вы настраиваете рекламную кампанию и хотите убедиться, что все теги срабатывают правильно.</p><p>✅ Плюсы: удобный интерфейс, анализ сразу всех тегов Google.</p><p>❌ Минусы: требует знаний о работе тегов.</p><p>А какими расширениями пользуетесь вы? Делитесь в комментариях!</p>]]></content:encoded>
    </item>
    <item>
      <title>Чек-лист по Node.js для новичков: обработка ошибок</title>
      <link>https://tproger.ru/articles/chek-list-dlya-node-js-novichkov--obrabotka-owibok-254149</link>
      <comments>https://tproger.ru/articles/chek-list-dlya-node-js-novichkov--obrabotka-owibok-254149?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chek-list-dlya-node-js-novichkov--obrabotka-owibok-254149</guid>
      <description><![CDATA[<p>Чек-лист для Node.js новичков. Показываем основные подходы к обработке ошибок. Рассматриваем пошаговую инструкцию и практические примеры ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chek-list-dlya-node-js-novichkov--obrabotka-owibok-254149">Чек-лист по Node.js для новичков: обработка ошибок</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 27 Jan 2025 10:04:22 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ошибки — неизбежная часть разработки, но в Node.js они могут не просто сломать приложение, а привести к утечкам данных, бесконечным зависаниям или даже сбоям всего сервера. Поэтому обработка потенциальных ошибок — не опциональный шаг, а ключевой элемент надежного кода. Сегодня разберем, какие бывают ошибки в Node, как правильно с ними работать и что иногда упускают новички.</p><h2>Типы ошибок в Node.js и основные подходы к их обработке</h2><h3>Синхронные ошибки</h3><p>В экосистеме Node синхронные ошибки представляют собой исключения, которые возникают в процессе выполнения кода и приводят к немедленному завершению программы, если их не обработать. Встречаются в тех случаях, когда код выполняется последовательно, без использования асинхронных операций. Разработчик, взаимодействующий с Node с нуля, должен понимать природу таких ошибок и уметь эффективно организовывать их обработку.</p><p>Если такая ошибка не перехвачена, она приведёт к аварийному завершению процесса. Какие есть примеры?</p><h4>Ошибки типа (TypeError, ReferenceError)</h4><p>Они возникают, когда код обращается к переменной, которая не определена, или передаёт в функцию аргумент неподходящего типа.</p><h4>Ошибки парсинга JSON</h4><p>Если переданный JSON-строковый объект невалиден, JSON.parse() выбросит исключение.</p><h4>Деление на ноль или некорректные математические операции</h4><p>JavaScript допускает деление на ноль, но оно может приводить к логическим ошибкам.</p><p>Но как правильно обрабатывать синхронные ошибки?</p><h4>Используем try...catch</h4><p>Классический способ перехвата ошибок в синхронном коде — использование конструкции try...catch.</p><h4>Генерируем пользовательские ошибки</h4><p>Можно явно выбрасывать ошибки с пояснением:</p><h4>Используем process.on('uncaughtException', callback)</h4><p>Node позволяет перехватывать необработанные ошибки глобально:</p><p>Синхронные ошибки в Node могут возникать по разным причинам: неверный тип данных, ошибки в логике или работе с JSON и т.д.. При работе важно помнить, что их можно перехватывать try...catch, выбрасывать вручную с пояснениями и даже обрабатывать глобально с помощью process.on(). Это снижает вероятность неожиданного завершения работы сервера и повышает надежность приложений.</p><h3>Асинхронные ошибки</h3><p>В отличие от синхронных, асинхронные ошибки в Node не прерывают выполнение кода немедленно, а возникают в процессе работы асинхронных операций. Это делает их обработку более сложной, поскольку ошибки могут всплывать после завершения основной логики программы.</p><p>Асинхронные ошибки в Node могут проявляться в трёх основных сценариях:</p><ol><li>Ошибки в коллбэках;</li><li>Ошибки в промисах;</li><li>Ошибки в async/await.</li></ol><p>Разработчик должен уметь обрабатывать потенциальные ошибки во всех этих случаях, чтобы избежать непредсказуемого поведения приложения.</p><h4>Ошибки в коллбэках</h4><p>Коллбэк-функции — один из старейших способов работы с асинхронностью в Node. Однако при их использовании легко столкнуться с ошибками, если не следить за правильной передачей аргументов и выполнением условий.</p><p>Пример: ошибка внутри коллбэка</p><p>Здесь, если файл nonexistent.txt отсутствует, в err передается ошибка, и программа не падает, а просто выводит сообщение. Однако, если бы в коде не было проверки if (err), приложение завершилось бы при попытке обработать data.</p><p>Как правильно обрабатывать ошибки в коллбэках?</p><ol><li>Всегда проверять аргумент err;</li><li>Передавать ошибки дальше, если не знаем, как с ними работать.</li></ol><p>Пример обработки ошибки и её проброса:</p><h4>Ошибки в промисах</h4><p>Промисы — более современный способ работы с асинхронностью в Node. Они позволяют избежать глубокой вложенности (callback hell) и обеспечивают удобный механизм обработки ошибок.</p><p>Пример: промис с ошибкой</p><p>Здесь, если в fetchData произойдёт ошибка (reject вызывается с new Error()), она будет перехвачена в .catch().</p><p>Как правильно обрабатывать ошибки в промисах?</p><ol><li>Использовать .catch() для перехвата ошибок;</li><li>Использовать .finally(), если нужно выполнить код в любом случае;</li><li>Не забывать возвращать промисы из функций.</li></ol><p>Пример корректной обработки:</p><h4>Ошибки в async/await</h4><p>async/await — современный способ работы с асинхронным кодом, который позволяет писать его в стиле синхронного. Однако ошибки в таком коде не всегда очевидны, особенно если промисы не обернуты в try...catch.</p><p>Пример ошибки в async/await:</p><p>Если getUser() выбросит ошибку, программа аварийно завершится. Чтобы избежать этого, нужно использовать try...catch.</p><p>Как правильно обрабатывать ошибки в async/await?</p><ol><li>Оборачивать вызовы await в try...catch;</li><li>Использовать catch() для перехвата на уровне вызова.</li></ol><p>Пример правильной обработки:</p><p>Или можно обработать ошибку прямо в .catch():</p><p>Асинхронные ошибки в Node могут проявляться в коллбэках, промисах и async/await. Каждый из этих подходов требует своей стратегии обработки ошибок:</p><ul><li>В коллбэках всегда проверяйте err;</li><li>В промисах используйте .catch() и .finally();</li><li>В async/await оборачивайте код в try...catch.</li></ul><p>Грамотная обработка ошибок в асинхронном коде — залог стабильности и предсказуемости работы Node-приложения.</p><h2>Чек-лист для новичков: как правильно обрабатывать ошибки в Node.js</h2><p>Ошибки в коде неизбежны, но грамотная обработка позволяет минимизировать их влияние на работу приложения. Даже если вероятность проблемы кажется низкой, её игнорирование может привести к неожиданным сбоям, утечке данных и того хуже. Рассмотрим, какие шаги должен предпринять новичок, чтобы сделать своё приложение в Node.js устойчивым к ошибкам.</p><h3>Всегда обрабатывайте ошибки, даже если они маловероятны</h3><p>Игнорирование ошибок может привести к фатальным последствиям: например, неожиданное исключение может привести к падению всего сервера. Поэтому всегда старайтесь обрабатывать даже маловероятные ошибки.</p><p>Пример ошибки без обработки:</p><p>Этот код вызовет исключение SyntaxError и остановит выполнение программы.</p><p>Правильный вариант с обработкой:</p><p>Даже если кажется, что JSON всегда будет корректным, лучше обработать его парсинг в try...catch, чтобы избежать сбоев.</p><h3>Используйте централизованный обработчик ошибок (middleware в Express)</h3><p>Если в вашем приложении на Express.js ошибки обрабатываются в каждом обработчике маршрута отдельно, это приведёт к дублированию кода. Вместо этого используйте централизованный middleware.</p><p>Что делать с централизованным обработчиком ошибок в Express?</p><ol><li>Определите middleware для обработки ошибок;</li><li>Все ошибки передавайте через next(error);</li><li>Express автоматически передаст ошибку в обработчик.</li></ol><p>Пример:</p><p>Теперь любая ошибка, возникшая в обработчиках маршрутов, будет передаваться в этот middleware, логироваться и возвращать корректный ответ клиенту.</p><h3>Логируйте ошибки (например, с помощью Winston или Pino)</h3><p>Логирование ошибок помогает отслеживать сбои и анализировать их причины. В продакшен-приложениях нельзя ограничиваться console.log() — лучше использовать специализированные библиотеки.</p><p><b>Как работает Winston?</b></p><p>Winston — это гибкий логгер для Node.js, поддерживающий сохранение логов в файлы, базу данных и удалённые сервисы.</p><p>Установка:</p><p>Настройка логгера:</p><p>Использование в коде:</p><p>Теперь ошибки будут логироваться как в консоли, так и в файле errors.log.</p><h3>Генерируйте пользовательские ошибки через Error (или свои классы ошибок)</h3><p>Вместо простых строковых сообщений об ошибках используйте объекты Error или создавайте собственные классы ошибок для лучшей структуризации.</p><p>Простой пример с Error:</p><p>Создание собственного класса ошибок:</p><p>Использование классов ошибок делает код более читаемым и удобным для отладки.</p><h3>Не забывайте про process.on('unhandledRejection') и process.on('uncaughtException')</h3><p>В приложениях на Node.js есть два типа необработанных ошибок, которые могут привести к завершению процесса:</p><ul><li>unhandledRejection — когда промис отклонён (Promise.reject()), но у него нет обработчика .catch();</li><li>uncaughtException — когда код выбрасывает исключение, но оно не обрабатывается try...catch.</li></ul><p>Чтобы защититься, добавьте обработчики для глобальных ошибок:</p><p>Эти обработчики помогут отлавливать неожиданные ошибки и предотвращать аварийное завершение программы.</p><h3>Добавьте тесты для проверки поведения вашего кода при ошибках</h3><p>Тестирование обработки ошибок помогает убедиться, что приложение корректно реагирует на сбои. Поэтому используйте Jest для тестирования.</p><p>Пример теста на обработку ошибок с Jest:</p><p>Регулярные тесты помогут выявлять проблемы до развертывания в продакшен.</p><p>Резюмируем:</p><ul><li>Обрабатывайте ошибки, даже если они маловероятны — лучше перестраховаться, чем допустить неожиданный сбой.</li><li>Используйте централизованный обработчик ошибок (middleware) в Express — это упростит код и улучшит поддержку.</li><li>Логируйте ошибки (Winston, Pino) — так вы сможете отслеживать и анализировать сбои.</li><li>Создавайте собственные классы ошибок — это сделает код чище и понятнее.</li><li>Обрабатывайте глобальные ошибки (unhandledRejection, uncaughtException) — чтобы сервер не падал неожиданно.</li><li>Пишите тесты на обработку ошибок — так ваш код будет надёжнее.</li></ul><h2>Практические примеры: обработка ошибок в Node.js</h2><p>Ошибки — неотъемлемая часть разработки, и их грамотная обработка играет ключевую роль в создании надёжных приложений. Рассмотрим практические примеры реализации обработки ошибок в API на Express, создания пользовательских классов ошибок и настройки глобального обработчика.</p><h3>Обработка ошибок в API с использованием Express</h3><p>Для примера создадим маршрут, который вызовет ошибку, и настроим обработчик:</p><p>Что здесь важно?</p><ul><li>Передача ошибок через next(error) — это стандартный способ уведомить Express о том, что произошла ошибка;</li><li>Централизованный обработчик (middleware) позволяет управлять ошибками в одном месте.</li></ul><h3>Пример пользовательского класса ошибок</h3><p>Иногда стандартного объекта Error недостаточно для описания специфики ошибки. В таких случаях можно создать собственный класс:</p><p>Что здесь важно?</p><ul><li>Так можно чётко разделять типы ошибок;</li><li>Так можно упростить добавление новой логики обработки для каждого типа ошибок.</li></ul><h3>Как настроить глобальный обработчик ошибок</h3><p>Некоторые ошибки не обрабатываются в отдельных блоках try...catch или маршрутах. Для таких ситуаций нужны глобальные обработчики ошибок.</p><h4>Глобальная обработка unhandledRejection и uncaughtException</h4><p>Глобальные обработчики защищают приложение от аварийных завершений:</p><p>Что здесь важно?</p><ul><li>unhandledRejection — позволяет обрабатывать промисы без catch;</li><li>uncaughtException — защищает приложение от ошибок, не пойманных в try...catch.</li></ul><p>Пример с промисом:</p><p>Обработка ошибок — обязательная часть разработки в Node.js, особенно для приложений в продакшене. Рассмотренные примеры помогут программисту:</p><ul><li>Правильно организовать обработку ошибок в API;</li><li>Создавать пользовательские классы ошибок для улучшения читаемости и поддержки кода;</li><li>Настраивать глобальные обработчики, чтобы защитить приложение от необработанных ошибок.</li></ul><h2>Частые ошибки при обработке ошибок в Node.js</h2><p>Даже опытные разработчики иногда совершают ошибки при обработке. Недочёты могут привести к неожиданным сбоям, утечкам данных или усложнению отладки. Рассмотрим наиболее распространённые ошибки, которые допускают программисты, и разберём, как их избежать.</p><h3>Пропуск ошибок в асинхронных функциях</h3><p>Асинхронный код в Node.js требует особого внимания, поскольку ошибки в промисах и async/await могут не перехватываться автоматически.</p><h4>Ошибка: нет обработки ошибок в промисах</h4><p>Если файл не существует, программа завершится с ошибкой UnhandledPromiseRejectionWarning.</p><h4>Правильный вариант: обработка через try...catch</h4><p>Теперь даже если файл отсутствует, приложение не вылетит, а отобразит сообщение об ошибке.</p><p>Запоминаем:</p><ul><li>Всегда используйте try...catch внутри async-функций;</li><li>При использовании промисов добавляйте .catch(), чтобы предотвратить unhandledRejection;</li><li>Используйте глобальный обработчик process.on("unhandledRejection"), если работаете с большим количеством промисов.</li></ul><h3>Логирование конфиденциальных данных</h3><p>Логирование — полезная практика, но если неосторожно записывать ошибки в логи, можно случайно сохранить конфиденциальные данные — пароли, токены или платежные данные.</p><h4>Ошибка: логирование чувствительных данных</h4><p>Ошибка здесь в том, что в логи попадает пароль пользователя.</p><h4>Правильный вариант: фильтрация логов</h4><p>Запоминаем:</p><ul><li>Не логируйте req.body, req.headers, req.query без фильтрации;</li><li>Используйте безопасные библиотеки для логирования, например, winston или pino, с возможностью маскировки данных;</li><li>Избегайте передачи ошибок клиенту без обработки — error.message может содержать внутренние данные системы.</li></ul><h3>Попытка поглощать ошибки вместо их корректной обработки</h3><p>Некоторые разработчики, чтобы избежать сбоев, просто подавляют ошибки, не анализируя их причины. Это приводит к тому, что ошибки замалчиваются, а баги остаются незамеченными.</p><h4>Ошибка: пустой catch-блок</h4><p>Здесь ошибка просто пропадает — приложение продолжает работать, но данные не загружаются, и отладка становится сложнее.</p><h4>Правильный вариант: логирование и повторная обработка</h4><p>Запоминаем:</p><ul><li>Не подавляйте ошибки, если они могут повлиять на логику приложения;</li><li>Логируйте ошибки и передавайте их на следующий уровень обработки, если они критичны;</li><li>Используйте автоматический перезапрос при сбоях, если это возможно (например, с помощью retry-механизмов).</li></ul><p>Обработка ошибок в Node.js — не просто техническая деталь, а критически важная часть разработки. Проблемы могут возникнуть в любом месте кода: от синхронных операций до асинхронных вызовов, API-запросов и работы с базами данных. Следование простым правилам поможет разработчику (будь то джун или сеньор) писать более устойчивый код, избегать критичных багов и создавать по-настоящему надёжные приложения в Node.js.</p>]]></content:encoded>
    </item>
    <item>
      <title>Вас заметили: как можно деанонимизировать юзеров в Telegram через паки кастомных эмоджи</title>
      <link>https://tproger.ru/articles/vas-zametili--kak-mozhno-deanonimizirovat-yuzerov-v-telegram-cherez-paki-kastomnyh-emodzhi</link>
      <comments>https://tproger.ru/articles/vas-zametili--kak-mozhno-deanonimizirovat-yuzerov-v-telegram-cherez-paki-kastomnyh-emodzhi?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/vas-zametili--kak-mozhno-deanonimizirovat-yuzerov-v-telegram-cherez-paki-kastomnyh-emodzhi</guid>
      <description><![CDATA[<p>Деанонимизация в Telegram через наборы эмоджи. Показываем уязвимости и методы для деанона пользователей. Рассматриваем основные меры предосторожности ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/vas-zametili--kak-mozhno-deanonimizirovat-yuzerov-v-telegram-cherez-paki-kastomnyh-emodzhi">Вас заметили: как можно деанонимизировать юзеров в Telegram через паки кастомных эмоджи</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Взлом]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 20 Jan 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Кастомные эмоджи — те самые смайлы, по которым можно понять, есть у пользователя премиум-подписка или нет. Есть паки как от разработчиков, так и от обычных юзеров. В Telegram кастомные эмоджи работают следующим образом (хотя вы это и так уже знаете):</p><ol><li>Пользователь скачивает специальный набор (пак) эмоджи;</li><li>Эти эмоджи становятся доступны в личных и групповых чатах, а также в комментариях на каналах;</li><li>Если кто-то видит необычный смайл, он может узнать, из какого набора он взят, и тоже его скачать.</li></ol><p>Создать собственный пак тоже легко, особенно, если вы уже проходили этот процесс со стикерами. Бот тот же самый — @Stickers. Вот алгоритм:</p><ol><li>Открываем бот, вводим /start и для эмоджи выбираем /newemojipack. На выбор: анимированные эмоджи, видеоэмоджи и статичные.</li><li>Называем пак.</li><li>Отправляем боту картинки или анимации в виде файлов, которые станут смайлами. По требованиям: для статичных эмоджи — PNG/WEBP, для видео и анимированных — WEB/TGS, без звука, длительность максимум 3 секунды.</li><li>Задаем каждому эмоджи из набора аналог из стандартных смайлов;</li><li>Когда добавляем все, что хотели, запускаем команду /publish.</li><li>Прописываем короткий юзернейм для пака, например, @tprogerpack — он и будет ссылкой.</li></ol><p>Действительно, создать свой пак или добавить уже существующий — проще простого. Правда, есть нюанс: вас могут скомпрометировать. Ниже разбираемся, почему это может произойти.</p><h2>Почему кастомные эмоджи уязвимы</h2><p>На самом деле не только они, а, например, еще стикеры и боты. Казалось бы, кастомные эмоджи — просто прикольное дополнение к переписке и стилю аккаунта, но, оказывается, через них можно узнать о вас важную информацию, и вот почему:</p><ul><li>У каждого пака свой уникальный идентификатор. Если вы используете эмоджи из редкого или персонализированного пака, это оставляет так называемый «цифровой отпечаток». Его можно легко идентифицировать в открытых чатах или каналах. Например, если пользователь скачал пак с мемами своей компании и активно использует эти эмоджи, можно выяснить, где он живет и чем увлекается;</li><li>Telegram позволяет легко находить сообщения в публичных чатах и каналах, где использовались те или иные эмоджи. Если эмоджи из вашего пака появляются в нескольких местах, злоумышленник может собрать все ваши сообщения из этих чатов, даже если вы писали под разными никами. Допустим, используете редкий эмоджи с изображением персонажа из аниме. Хакер может найти ваши сообщения в нескольких чатах и таким образом связать ваши аккаунты в разных сообществах;</li><li>Некоторые кастомные эмоджи создаются специально для каналов или чатов, например, в паблике стримера. Если вы их используете в других местах, то очевидно, что смотрите этого стримера. Да, из 100 000 подписчиков вычислить именно вас будет сложно, но возможно;</li><li>Когда создаёте собственный пак эмоджи и используете его в пабликах или открытых чатах, это фактически становится вашей уникальной меткой. Даже если кто-то другой добавит ваш пак, вероятность его использования останется низкой, а вас легко узнают (если, правда, этот пакт не выстрелит на многомиллионную аудиторию, как с енотом Педро или котами из ТикТока).</li></ul><h2>Как это работает</h2><p>Переходим к технической стороне вопроса. В Телеграме у каждого пака с эмоджи или стикерами свой уникальный ID, который можно получить через API. Один из юзеров таким образом <a href="https://hackernoon.com/whats-wrong-with-stickers-in-telegram-deanonymize-anonymous-channels-in-two-clicks">вычислил</a> (точнее, ему помогли) создателя стикер-пака <a href="https://t.me/addstickers/HotCherry?ref=hackernoon.com">https://t.me/addstickers/HotCherry</a>.</p><p>Дисклеймер: это не совсем законно, поэтому мы рассмотрим этот пример, чтобы показать вам, что любая система уязвима.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-01-17/dd02b0ec-ea32-40ce-a015-3998127eb317.png" alt="" /></figure><p>Главное поле здесь — ID. Да, на первый взгляд он кажется уникальным идентификатором стикерпака и никак не поможет вычислить аккаунт автора. Но не устанем повторять: есть один нюанс.</p><p>Существует операция над числом, которая называется двоичный сдвиг вправо. Суть в том, чтобы сдвинуть все биты числа вправо на определенное количество цифр, а свободное пространство слева заполнить нулями. Автор эксперимента делает этот сдвиг на 32, используя пример числа, возвращаемого API.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-01-17/155b594c-6da5-41fd-838c-21c6a20bd335.png" alt="" /></figure><p>Число 1391391008142393345 можно представить в двоичной системе. Так мы доходим от 0 до 32. Если перевести в обычное значение, то получится более короткий и узнаваемый идентификатор 323958464. Так автору удалось выяснить, что это не идентификатор стикерпака, а идентификатор конкретного пользователя Telegram.</p><p>Пользователь с этим идентификатором в Telegram — создатель стикерпака.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-01-17/296be471-b746-4e9a-9b3a-25f5e8ecd9d4.png" alt="" /></figure><p>Но есть проблема: по числовому ID, который мы получаем, нельзя напрямую определить, что это за пользователь — его имя, аватар и так далее, так как в API просто нет такого метода. Но как же автору это удалось?</p><p>Существует обратный метод API, позволяющий получить профиль пользователя и его ID по имени. Этот метод вызывается каждый раз, когда вы открываете ссылку [t.me/&lt;login](http://t.me/&lt;login) user&gt;  или ищете по имени в Telegram.</p><p>Он просканирует всех пользователей Telegram (например, взяв их из всех публичных чатов) и составит соответствие: ID&lt;&gt;имя пользователя.  Такое можно проделать с любым стикерпаком или паком с эмоджи, опубликованном в конкретном канале, и есть шанс выйти на админа.</p><h2>Maltego, или как парсить данные не вручную</h2><p>Под Телеграм уже написали инструменты, которые помогают собирать и анализировать данные. И Maltego — одна из таких фич, которая работает с открытыми источниками (OSINT). Она лежит в открытом доступе на <a href="https://github.com/vognik/maltego-telegram">Github</a>. Maltego может помочь деанонимизировать пользователя через кастомные эмоджи, если они оставляют за собой «цифровой след». Уже знакомый нам экспериментатор тоже поюзал этот инструмент, для этого ему еще понадобился Python — почитать подробнее можно в той же <a href="https://hackernoon.com/whats-wrong-with-stickers-in-telegram-deanonymize-anonymous-channels-in-two-clicks">статье</a>.</p><p>Рассказываем, как это происходит:</p><h2>1. Уникальность кастомных эмоджи</h2><p>Как мы уже писали, каждый кастомный эмоджи принадлежит определённому набору (паку), который имеет уникальный ID. Если вы используете редкий пак, это как отпечаток пальца — его можно легко отследить.</p><h2>2. Сбор данных о сообщениях в пабликах</h2><p>Maltego может анализировать публичные чаты и каналы Telegram:</p><ul><li>Найти все сообщения, где использовались ваши кастомные эмоджи;</li><li>Определить, в каких каналах или группах вы активно пишете;</li><li>Собрать сообщения, даже если вы используете разные никнеймы.</li></ul><p>Например, вы используете редкий эмоджи с символом любимого сериала в двух разных чатах. Maltego покажет, что эти сообщения принадлежат одному пользователю.</p><h2>3. Связывание аккаунтов</h2><p>Если вы используете кастомные эмоджи в нескольких местах, Maltego об этом тоже узнает. Даже когда стараетесь оставаться анонимным, использование одного и того же эмоджи выдаёт, что оба аккаунта принадлежат вам.</p><p>Например, в одном чате вы пишете с анонимного аккаунта, а в другом — с основного, но используете одинаковые эмоджи. Maltego это заметит.</p><h2>4. Поиск пользователей с таким же паком эмоджи</h2><p>Если злоумышленник знает ID вашего кастомного пака, Maltego может:</p><ul><li>Найти, кто добавил этот пак в Telegram;</li><li>Узнать, кто ещё использует эти эмоджи;</li><li>Связать вас с теми, кто скачал этот пак.</li></ul><p>Например, вы создали пак эмоджи для небольшой компании. Если злоумышленник найдёт ваши сообщения, он может вычислить всех, кто скачал этот набор, и привязать их к вашей организации.</p><h2>5. Использование API для анализа</h2><p>Maltego подключается к Telegram API, который предоставляет доступ к информации о публичных чатах и пользователях. Так он может:</p><ul><li>Найти все сообщения с конкретным эмоджи;</li><li>Узнать, кто чаще всего использует эмоджи из определённого пака;</li><li>Собрать данные и построить граф связей между пользователями.</li></ul><p>Например, злоумышленник через Maltego находит, что эмоджи из вашего пака часто используются в конкретном канале, и банально связывает вас с этим каналом и всеми, кто в нем состоит.</p><h2>Почему это опасно</h2><p>Как говорили в фильме «Кто я», любая система уязвима, и об этом нужно помнить всегда. Maltego или другие подобные ему инструменты не могут напрямую «взломать» вас, но их главная сила — в аналитике и парсинге. Даже одно сообщение, которое вы оставили в паблике с кастомным эмоджи, может раскрыть ваши интересы, знакомства, активность и даже локацию. А потом уже дело за малым.</p><h2>Как предотвратить деанонимизацию: методы</h2><p>Кастомные эмоджи или стикерпаки в Telegram могут раскрыть больше информации о вас, чем вы думаете — достаточного одного сообщения. Но есть несколько простых советов, которые помогут оставаться в безопасности (насколько это возможно).</p><h2>Не используйте редкие эмоджи в публичных чатах</h2><p>Если ваш эмоджи из уникального или вашего личного пака, его легко отследить. Вместо этого выбирайте популярные паки, которые используют тысячи людей. А если и хотите пользоваться локальными, то делайте это в закрытых чатах с друзьями/коллегами.</p><h2>Не переусердствуйте с эмоджи</h2><p>Чем чаще вы используете редкие эмоджи, тем больше информации оставляете. Лучше ограничить их использование в публичных сообщениях.</p><h2>Настройте приватность в Telegram</h2><p>В настройках Telegram есть функции, которые помогут скрыть ваши личные данные:</p><ul><li>Скрывайте свой номер телефона, чтобы его не могли увидеть другие пользователи;</li><li>Сделайте так, чтобы ваш аватар и информация о последнем посещении видели только друзья или те, кого вы добавляете в контакты. Хотя, конечно, лучше вручную составить список юзеров, у кого есть доступ к вашим данным;</li><li>Отключите доступ к вашим данным для незнакомых людей. Например, поставьте настройки, чтобы при пересылке сообщения ваш аккаунт оставался анонимным.</li></ul><h2>Используйте разные аккаунты</h2><p>Если вы активно общаетесь в публичных чатах, заведите отдельный аккаунт для этой активности. Это поможет отделить личную жизнь от публичной.</p><h2>Политика Telegram по защите данных</h2><p>Telegram утверждает, что заботится о безопасности пользователей, но есть нюансы, которые стоит учитывать:</p><ul><li>Сообщения в публичных чатах открыты для анализа. Если вы пишете в большом канале или группе, ваши сообщения все равно попадают в открытый доступ, и их можно найти с помощью парсинга;</li><li>Доступ к данным через Telegram API. API позволяет извлекать информацию о пользователях и их действиях. Отключить его никак нельзя, поэтому старайтесь не использовать уникальные эмоджи в пабликах;</li><li>Используйте секретные чаты. Только секретные чаты в Telegram имеют сквозное шифрование — никто, кроме участников, не сможет получить доступ к сообщениям. Плюс можно поставить полное удаление переписки или определенных сообщений через какое-то время.</li></ul><p>Полная конфиденциальность практически невозможна — всегда нужно помнить о том, что злоумышленники могут подобраться к вашим данным очень близко. Но если следовать простой «технике безопасности», то вычислить вас будет сложнее. Не используйте редкие кастомные эмоджи, проверьте настройки приватности аккаунта и, как говорится, stay safe.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как работать с JSON в веб-разработке?</title>
      <link>https://tproger.ru/articles/kak-rabotat-s-json-v-veb-razrabotke-</link>
      <comments>https://tproger.ru/articles/kak-rabotat-s-json-v-veb-razrabotke-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Елизавета Малышева]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-rabotat-s-json-v-veb-razrabotke-</guid>
      <description><![CDATA[<p>Что такое JSON. Показываем основы веб-разработки с помощью JSON. Рассматриваем пошаговую инструкцию, как правильно управлять данными ✔ Tproger </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-rabotat-s-json-v-veb-razrabotke-">Как работать с JSON в веб-разработке?</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[XML]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 17 Jan 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>JSON может убить ваш сайт на часы, а может, и больше. Хотите узнать, как этого избежать? Тогда читайте дальше: разберем самые частые ошибки и расскажем, как правильно управлять данными.</p><h2>Что такое JSON</h2><p>JSON или JavaScript Object Notation — формат для обмена данными. Его используют в веб-разработке, чтобы передать числовую информацию от клиента к серверу и наоборот. По сути это просто строка, но с нюансами.</p><p>JSON — стандарт в веб-разработке, так как его текстовая структура легко читается как человеком, так и компьютером. Давайте посмотрим, из чего он может состоять:</p><ul><li><b>Объекты </b>— пары “ключ-значение” в фигурных скобках. Выглядят так же, как обычные JS-объекты;</li><li><b>Массивы </b>— упорядоченные значения. Заключаются в квадратные скобки и отделяются запятой;</li><li>Ключи — строки, которые обязательно в двойных кавычках. Одинарные не подойдут;</li><li>Значения — могут быть строками в двойных кавычках, числами, логическими значениями, массивами, объектами или null.</li></ul><p>Мы не зря упоминаем двойные кавычки. Очень важно следить за ними, иначе сервер или ваш сайт не смогут обработать JSON.</p><figure><img src="https://media.tproger.ru/user-uploads/105990/2025-01-10/2881af4f-84d3-46b4-9f97-86c49b1e3c17.png" alt="" /></figure><p>Пример JSON-документа:</p><p>В этом примере объект содержит четыре ключа:</p><ul><li>name — строка,</li><li>type — строка,</li><li>topics — массив строк,</li><li>published — логическое значение, true.</li></ul><p>Этот JSON описывает воображаемую статью, у которой есть темы, название и статус публикации.</p><h2>Зачем нужен JSON, если есть XML?</h2><figure><img src="https://media.tproger.ru/user-uploads/105990/2025-01-10/52e20503-f9b7-4b82-8959-0259db56f08d.png" alt="" /></figure><p>До JSON разработчики использовали XML. Вот основные отличия:</p><figure><img src="https://media.tproger.ru/user-uploads/105990/2025-01-10/f33c9cfe-801c-49d2-ab39-d4f86994a5c1.png" alt="" /></figure><p>Давайте разберём все пункты и посмотрим, в чём же конкретно хорош JSON.</p><h3>Синтаксис</h3><h4>JSON</h4><p>Выглядит как обычный JavaScript-объект.</p><p>Пример:</p><p>Мы создали объект с двумя ключами. Имя –– John, возраст –– 30. Это упрощённый вариант хранения данных о пользователе. Также можно добавить почту, ник, город и так далее.</p><h4>XML</h4><p>XML или (Extensible Markup Language) –– посложнее, так как использует закрывающиеся теги. Это делает его визуально более «шумным» и трудным для восприятия. Особенно если XML-данных много.</p><h3>Размер данных</h3><h4>JSON</h4><p>JSON компактнее, в нём нет лишних тегов и атрибутов. Он лучше подходит для веба, так как важна минимизация. Чем данные легче, тем быстрее работает сайт.</p><h4>XML</h4><p>XML объемнее, потому что каждый элемент должен быть обёрнут в открывающий, а потом закрывающий тег.</p><h3>Легкость парсинга</h3><h4>JSON</h4><p>JSON легко парсить. В JavaScript достаточно использовать JSON.parse(), чтобы преобразовать JSON-строку в JS-объект.</p><p>Пример:</p><p>Здесь мы поместили JSON-строку в переменную и затем распарсили её в другую переменную с помощью функции JSON.parse().</p><h4>XML</h4><p>XML-файлы могут быть большими, с множеством вложенных тегов: чтобы распарсить такие данные, нужно много времени и ресурсов.</p><p>Пример на JavaScript:</p><p>Что здесь происходит:</p><ol><li>Создаем строку, которую хотим превратить в XML. Она содержит элемент  с вложенными элементами;</li><li>Используем объект DOMParser. Он превращает текстовые строки в XML-документы;</li><li>Метод parseFromString() выполняет это преобразование. После этого js работает с переменной через DOM-методы;</li><li>Используем метод getElementsByTagName(), чтобы получить значение элемента . Он возвращает массив элементов с указанным тегом;</li><li>Указываем индекс [0] для выбора первого элемента, а затем получаем его текстовое содержимое через childNodes[0].nodeValue.</li></ol><p>Разница очевидна:</p><ul><li>Для JSON мы можем сразу преобразовать строку в объект с помощью JSON.parse();</li><li>Для XML требуется больше шагов: разбор строки в документ и использование методов DOM для извлечения данных.</li></ul><h3>Читаемость</h3><h4>JSON</h4><p>JSON легко читать, потому что его структура похожа на JavaScript-объект. Он не требует лишних символов и тегов, поэтому визуально лаконичен и прост.</p><h4>XML</h4><p>XML выглядит сложнее. Теги для описания структуры делают документ более громоздким и менее читаемым. Особенно если в файле много вложенных элементов.</p><figure><img src="https://media.tproger.ru/user-uploads/105990/2025-01-10/4c30c1ee-6657-4830-b3df-aa0c8073fd9d.png" alt="" /></figure><h2>Создаём и парсим JSON</h2><p>JSON-документы можно создать вручную. Главное, надо соблюдать синтаксические правила:</p><ul><li>Использовать двойные кавычки для строк;</li><li>Разделять ключи и значения двоеточием, как и в JS-объектах;</li><li>Ставить запятые между ключами.</li></ul><p>А можно использовать <a href="https://www.convertsimple.com/convert-javascript-to-json/">конвертер</a>. Вы ему JS-объект, а он из него  ––  JSON.</p><p>В разных языках  –– разные инструменты для работы с JSON. Разработчики используют встроенные средства языков программирования или сторонние библиотеки:</p><ul><li><b>JavaScript</b>: Методы JSON.stringify() и JSON.parse();</li><li><b>Python</b>: Модуль json для сериализации и десериализации;</li><li><b>PHP</b>: Функции json_encode() и json_decode();</li><li><b>Node.js</b>: Встроенные методы для работы с JSON в модуле fs.</li></ul><h3>Работа с JSON в Python</h3><p>Что тут происходит:</p><ol><li><b>Импортируем json</b>. Это встроенная библиотека Python. Она работает с данными в формате JSON;</li><li><b>Создаём данные для сериализации </b>–– Python-словарь data, который содержит пары ключ-значение. Не пугайтесь нового слова «сериализация». Это всё то же преобразование одного формата в другой;</li><li><b>Используем </b>метод json.dumps() для преобразования Python-объекта в строку в формате JSON. Результатом будет строка, которую можно передать серверу, сохранить в файл или обработать в другой программе;</li><li><b>Десериализириуем данные  </b>с помощью метода json.loads(). Он преобразует JSON-строку обратно в Python-объект;</li><li><b>Выводим десериализованные данные </b>в консоль. В данном случае это словарь parsed_data, который будет точно таким же, как и исходный словарь data.</li></ol><h3>Работа с JavaScript</h3><p>Методы JSON.stringify() и JSON.parse() позволяют преобразовывать данные из объекта в JSON-строку и обратно.</p><p>Пример:</p><p>Метод fetch() используется для отправки HTTP-запросов с JSON-данными:</p><p>Что здесь происходит:</p><ul><li>Мы указываем, куда нужно сделать запрос и что нужно передать серверу. Посылка –– это значение в ключе body. Если не обернуть объект с данными в JSON.stringify(), то запрос упадёт. Так как этот метод превращает JS-объект в JSON-строку. Сервер умеет читать JSON, но не умеет работать с JS-объектами;</li><li>На предпоследней строке мы получаем ответ от сервера. А затем обязательно переводим его обратно, в удобоваримый для JS код.</li></ul><h2>Работа с JSON на сервере</h2><p>JSON незаменим в бэкэнде. Сервер присылает данные через REST API в  JSON. Поэтому в предыдущем блоке мы использовали на ответе метод .json(). Без него данные останутся обычной JSON-строкой.</p><p>Разберём примеры на разных языках.</p><h3>Пример реализации REST API на Node.js</h3><p>Здесь мы создаём приложение на основе Express. Оно слушает POST-запросы на маршруте /data и возвращает ответ в формате JSON с сообщением о том, что данные получены.</p><p>Для работы с JSON на сервере используем встроенную функцию express.json(), которая парсит данные, и метод res.json(), чтобы отправить ответ в формате JSON.</p><h3>Пример работы JSON в python-фреймворке Flask</h3><p>Что делаем:</p><ol><li><b>Импортируем необходимые библиотеки</b>: Flask, request, jsonify для создания нашего веб-приложения и обработки JSON-строк;</li><li><b>Создаем приложение </b>через экземпляр Flask;</li><li><b>Определяем маршрут  </b>/data и указываем, что функция handle_data() будет обрабатывать по этому маршруту POST-запросы;</li><li><b>Извлекаем JSON-данные из запроса </b>внутри функции. Получаем и преобразуем данные из тела запроса в JSON с помощью request.get_json();</li><li><b>Отправляем JSON-ответ</b>. Возвращаем клиенту JSON-ответ, содержащий полученные данные. Либо, если переменная data пуста, отправляем ошибку и 400 статус. И обязательно отлавливаем ошибки с помощью try-except;</li><li><b>Запускаем приложение</b>. Приложение запускается на сервере и слушает входящие запросы.</li></ol><h2>Что не так с JSON</h2><p>За простотой JSON скрываются ловушки, попадать в которые лучше не надо. Малейшая ошибка — и данные становятся нечитаемыми, а приложение падает. Разберём эти ловушки:</p><h3>Неправильная структура</h3><p>Забудете закрыть скобку, добавите не ту кавычку или поставите запятую в конце массива — и всё. Браузер или сервер выдадут ошибку. А если JSON создается динамически, найти проблему будет сложно.</p><p>Пример ошибки:</p><p>В этом примере после крайнего элемента массива стоит лишняя запятая. Исправленный вариант:</p><h3>Большие объемы данных</h3><p>JSON не предназначен для хранения огромных массивов данных. Обрабатывать большие файлы в браузере –– опасно для производительности. Ваш сайт может начать тормозить или вовсе зависнуть.</p><h3>Неэкранированные символы</h3><p>Забыли экранировать кавычку в строке? Получите ошибку. JSON требует строго соблюдать правила синтаксиса, иначе парсинг провалится.</p><p>Пример ошибки:</p><p>Здесь у нас дублирование. Нельзя помещать двойные кавычки внутрь таких же двойных кавычек:</p><p>Исправленный вариант:</p><h3>Уязвимая безопасность</h3><p><b></b> Если данные не проверяются, JSON может стать источником XSS-атак или привести к раскрытию конфиденциальной информации.</p><p>Пример ошибки:</p><p>Пользователь может отправить через поле ввода вредоносные данные. И получится вот такая история:</p><p>Решение: обязательно проверяйте входящие данные. Можно заменить опасные символы безопасными:</p><p>И уже эту строку отправить на сервер.</p><h2>Как избежать проблем с JSON?</h2><p>Чтобы работать с JSON безопасно и эффективно:</p><ul><li><b>Используйте валидаторы</b>. Перед передачей данных обязательно проверяйте JSON на синтаксические ошибки;</li><li><b>Сжимайте данные</b>. Уменьшайте размер JSON, удаляя лишние пробелы и символы, чтобы оптимизировать передачу и обработку;</li><li><b>Не доверяйте входящим данным</b>. Проверяйте и фильтруйте всё, что приходит от клиента или сторонних API;</li><li><b>Ограничивайте глубину вложенности</b>. Глубокая структура JSON может перегрузить обработчик и вызвать зависание.</li></ul><h3>Валидаторы JSON</h3><p>Перед отправкой проверьте свой JSON. Для этого можно использовать онлайн-валидаторы. Например, <a href="https://jsonlint.com/"> </a><a href="https://jsonlint.com">https://jsonlint.com</a>. Как он работает: вы прописываете вашу строку, а валидатор проверяет, нет ли в ней ошибок.</p><h3>Минификация JSON</h3><p>Для уменьшения размера JSON-строку можно минифицировать. Удалить пробелы и переносы строк. Пример минификации в Python:</p><h3>Обработка ошибок при работе с JSON</h3><p>Ошибки часто возникают из-за неправильного формата данных. Всех опасных мест не избежать. Но можно подстелить соломку.</p><p>Вот так обрабатываются возможные ошибки с JSON:</p><p>Что тут происходит:</p><ol><li><b>Получаем данные из localStorage</b>: Используется метод localStorage.getItem(), чтобы извлечь данные по указанному ключу key;</li><li><b>Проверяем на наличие данных</b>: Если данные отсутствуют –– null, выбрасывается ошибка с помощью throw;</li><li><b>Парсим данные</b>: Если данные есть, они парсятся через JSON.parse(). И на выходе получается JS-объект;</li><li><b>Обрабатываем ошибки</b>: В блоке catch ловятся все ошибки. Затем их можно обработать и отобразить пользователю в интерфейсе.</li></ol><p>Теперь даже если в LocalStorage не лежат нужные данные, приложение не упадёт.</p><p>В веб разработке без JSON никуда. Он лёгкий и гибкий. Но чтобы использовать эти преимущества, нужно научиться с ним взаимодействовать.</p><p>Для этого просто следуйте нашим правилам. Проверяйте свои JSON-строки, обрабатывайте ошибки и тестируйте приложение на корнер-кейсы. Тогда ваши сайты и приложения будут в безопасности. 🙂</p>]]></content:encoded>
    </item>
    <item>
      <title>Как парсить данные на Python: BeautifulSoup и Scrapy</title>
      <link>https://tproger.ru/articles/osnovy-parsinga-dannyh-na-python--beautifulsoup-i-scrapy</link>
      <comments>https://tproger.ru/articles/osnovy-parsinga-dannyh-na-python--beautifulsoup-i-scrapy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/osnovy-parsinga-dannyh-na-python--beautifulsoup-i-scrapy</guid>
      <description><![CDATA[<p>Парсинг сайтов на Python с BeautifulSoup и Scrapy: примеры кода, сравнение инструментов, динамический контент и советы по обходу блокировок. Читайте на Tproger.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/osnovy-parsinga-dannyh-na-python--beautifulsoup-i-scrapy">Как парсить данные на Python: BeautifulSoup и Scrapy</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Фреймворки и библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 08 Dec 2024 08:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Парсинг сайтов на Python автоматизирует сбор информации с сайтов — от цен конкурентов до контактов потенциальных клиентов. <b>Парсинг данных (web scraping)</b> — автоматизированный процесс извлечения информации с веб-страниц с помощью кода. Для этого используются две основные библиотеки: BeautifulSoup подходит для простых задач и небольших проектов, а Scrapy — для масштабного парсинга данных. Эта статья — часть нашего <a href="https://tproger.ru/articles/python--polnyj-putevoditel-dlya-razrabotchika">полного путеводителя по Python</a>.</p><p>Чтобы использовать эти инструменты, вспомним основы HTML, DOM-дерева и принципы работы динамических страниц.</p><p>BeautifulSoup — простая библиотека для парсинга HTML на Python: подходит для небольших задач, статических страниц и быстрых скриптов.</p><p>Scrapy — полноценный асинхронный фреймворк для масштабного парсинга: встроенные pipelines, управление прокси, ротация User-Agent и экспорт в JSON/CSV/XML.</p><p>Для динамических сайтов с JavaScript ни BeautifulSoup, ни Scrapy не работают напрямую — нужен Selenium или Playwright, имитирующий браузер.</p><p>Если сайт предоставляет API — всегда предпочитайте его парсингу: меньше нагрузка на сервер, структурированные данные, официальная документация.</p><p>Соблюдайте этику парсинга: уважайте robots.txt, делайте задержки между запросами 1–3 секунды и собирайте только те данные, которые действительно нужны.</p><h2>Основные понятия парсинга данных</h2><p><b>HTML-документ</b> — это текстовый файл с расширением .html. Он содержит набор элементов для отображения страницы в браузере.</p><p>Структура HTML-документа состоит из двух частей: <b>заголовка (head)</b> и <b>тела (body)</b>. Весь документ обрамляется корневым тегом html.</p><p>Заголовок содержит метаданные, стили, скрипты, заголовок страницы. В теле документа находятся теги и основной контент, который отображается в окне браузера.</p><p><b>DOM-дерево</b> — это представление HTML-документа в виде древовидной структуры объектов. Каждый элемент HTML становится узлом этого дерева. Благодаря DOM можно взаимодействовать с элементами страницы через JavaScript:</p><ul><li>получать доступ к содержимому,</li><li>изменять состояние тегов,</li><li>добавлять или удалять элементы.</li></ul><p>Корневой элемент DOM-дерева — тег html. От него идет разветвление на head и body — его прямых потомков. Остальные элементы образуют более глубокие уровни вложенности.</p><p><a href="https://software.hixie.ch/utilities/js/live-dom-viewer/">Тут</a> можно посмотреть, как выглядит DOM-дерево для определенного фрагмента кода.</p><p><b>Статические страницы</b> содержат фиксированный HTML. Его код не меняется после загрузки. По этой причине статические страницы проще парсить. Достаточно отправить HTTP-запрос и будет получен весь HTML-документ, из которого можно извлечь целевые теги. С этой задачей успешно справляются любые библиотеки для парсинга: Requests, BeautifulSoup, Urllib3 и другие.</p><p><b>Динамические страницы</b> формируют контент с помощью JavaScript после загрузки основного HTML. Контент может подгружаться через API, изменяться при взаимодействии пользователя или обновляться автоматически.</p><p>Простой HTTP-запрос не парсит динамически загруженные сайты. Для этого нужны инструменты, эмулирующие работу браузера. Например, <a href="https://tproger.ru/articles/selenium-pishem-parser-dlya-menyayushhegosya-sajta">Selenium WebDriver</a>. Он запускает браузер, выполняет JavaScript-код и парсит финальное DOM-дерево с динамическим контентом.</p><h2>Этические и юридические аспекты парсинга данных</h2><p>Парсинг не запрещен законодательством. Если ваша программа не выводит из строя сайты и не вредит бизнесу, то шансы на судебные иски стремятся к нулю.</p><p><b>Что можно делать</b>:</p><ul><li>Собирать информацию, которая находится в открытом доступе.</li><li>Парсить данные, не нагружая сайт и не мешая его работе.</li></ul><p><b>Чего нельзя делать</b>:</p><ul><li>Воровать закрытую информацию компаний.</li><li>Собирать личные данные пользователей (телефоны, адреса, паспортные данные).</li><li>Намеренно вредить работе сайта большим количеством запросов.</li></ul><p>Перед сбором данных задавайте себе простой вопрос: «Мне понравится, если кто-то соберет эту информацию обо мне?» Подумайте также о том, приносит ли ваш парсинг пользу другим людям или вы делаете это только ради собственной выгоды.</p><p>Если закон разрешает какие-то действия, это не значит, что их правильно делать с моральной точки зрения. Например, технически возможно собрать все комментарии человека в соцсетях, но будет ли это этично по отношению к нему?</p><p>Cобирайте только те данные, которые действительно нужны для вашей задачи. Не нужно сохранять личную информацию людей просто потому, что вы можете это сделать.</p><p>Если собираете данные временно, например, чтобы найти фальшивые отзывы на Яндекс Картах, а потом сразу удаляете личную информацию — это более приемлемо, чем создание постоянной базы данных о людях для продажи рекламодателям.</p><h2>BeautifulSoup: простой и удобный инструмент для парсинга</h2><p><b>BeautifulSoup</b> — это библиотека Python для извлечения данных из HTML и XML. Следуйте пошаговому руководству, чтобы установить BeautifulSoup.</p><p>Откройте терминал и выполните команду:</p><p>Установите парсер lxml:</p><p>Также понадобится библиотека requests для выполнения HTTP-запросов:</p><p>Самый простой парсер на BeautifulSoup:</p><h2>Основные функции и методы библиотеки</h2><p>Найти первый абзац:</p><p>Найти все абзацы:</p><p>Один элемент с классом 'content':</p><p>Все элементы с классом 'content':</p><p>Поиск ссылки по href:</p><p>Поиск по нескольким атрибутам:</p><p>Найти все абзацы с определенным классом:</p><p>Найти все ссылки внутри div с определенным id:</p><h2>Плюсы BeautifulSoup</h2><ul><li>Простой синтаксис, поэтому библиотекой пользуются даже начинающие разработчики.</li><li>Гибкий поиск элементов ищет теги по имени, классу, id, атрибутам. Можно комбинировать условия поиска и использовать CSS-селекторы.</li><li>Автоматическое исправление невалидного HTML. BeautifulSoup пытается восстановить неправильную структуру документа, что полезно при работе с некачественной версткой.</li><li>Низкие требования к ресурсам компьютера по сравнению с браузерными решениями вроде Selenium.</li></ul><h2>Недостатки BeautifulSoup</h2><ul><li>Нет поддержки JavaScript. Библиотека работает только со статическим HTML и не может обрабатывать динамически загружаемый контент.</li><li>Ограниченная производительность при работе с большими документами. Для парсинга крупных файлов лучше использовать потоковые парсеры.</li><li>Отсутствие встроенной поддержки асинхронности. Для параллельной обработки нескольких страниц требуются дополнительные библиотеки asyncio и aiohttp</li></ul><p>BeautifulSoup не подходит для парсинга сайтов с динамической загрузкой контента, высоконагруженных проектов. Для этих целей выбирайте фреймворк Scrapy.</p><h2>Scrapy: мощный фреймворк для парсинга больших объемов данных</h2><p><b>Scrapy </b>— это фреймворк для парсинга сайтов, построенный на асинхронной архитектуре. Рассмотрим его основные компоненты.</p><p><b>Пауки (Spiders) </b>— это классы, которые определяют как парсить конкретный сайт. В пауке указываются начальные URL-адреса, правила извлечения данных и переходов между страницами. Паук обходит страницы сайта и извлекает информацию с помощью CSS-селекторов или XPath-выражений.</p><p><b>Элементы (Items)</b> — это контейнеры для хранения извлеченных данных. Они похожи на словари Python, но предоставляют дополнительную валидацию полей. Items определяют структуру данных, которые будут собраны пауком.</p><p><b>Каналы обработки (Pipelines)</b> — это компоненты для обработки извлеченных данных. Каждый элемент проходит через цепочку pipeline-обработчиков. В pipeline можно выполнять очистку данных, удалять дубликаты, сохранять информацию в базу данных.</p><p>Парсинг HTML на Scrapy выглядит так:</p><ol><li>Паук отправляет запрос к сайту.</li><li>Получает ответ и извлекает данные.</li><li>Создает элементы с данными.</li><li>Передает элементы в pipeline.</li><li>Pipeline обрабатывает и сохраняет данные.</li></ol><h2>Установка и настройка Scrapy</h2><p>Откройте терминал и выполните команду::</p><p>Создайте новый проект:</p><p>Эта команда создаст структуру каталогов — файлы настроек и шаблоны пауков.</p><p>Файл settings.py содержит основные настройки проекта. Базовые параметры, которые требуют настройки:</p><ul><li>USER_AGENT = 'Mozilla/5.0...' (идентификация парсера).</li><li>ROBOTSTXT_OBEY = True (соблюдение правил robots.txt).</li><li>CONCURRENT_REQUESTS = 16 (количество одновременных запросов).</li><li>DOWNLOAD_DELAY = 1 (задержка между запросами).</li><li>COOKIES_ENABLED = False (использование cookies).</li></ul><p>Для создания нового паука используйте команду:</p><p>Пример простого паука:</p><p>Запуск паука выполняется командой:</p><p>Для сохранения результатов в файл:</p><p>Для обработки данных перед сохранением используется pipelines.py:</p><p>Активация pipeline происходит в settings.py:</p><h2>Плюсы Scrapy</h2><ul><li>Обрабатывает запросы асинхронно.</li><li>Автоматически управляет порядком обработки URL и перераспределяет нагрузку.</li><li>Легко добавлять прокси-серверы, ротацию User-Agent, обработку ошибок.</li><li>Встроенная поддержка экспорта в JSON, CSV, XML.</li></ul><h2>Недостатки Scrapy</h2><ul><li>Сложность отладки асинхронного кода.</li><li>Ограниченная поддержка JavaScript.</li></ul><h2>Сравнение BeautifulSoup и Scrapy</h2><p>Выбор инструмента зависит от масштаба задачи. Для извлечения данных с нескольких страниц достаточно BeautifulSoup. Для создания поискового робота или регулярного парсинга больших объемов данных оптимальным выбором будет Scrapy.</p><p><b>Парсинг на Python BeautifulSoup лучше подходит для</b>:</p><ul><li>Парсинга отдельных страниц.</li><li>Небольших скриптов.</li><li>Интеграции в существующие проекты.</li></ul><p>BeautifulSoup дает разработчику полную свободу в организации кода и выборе дополнительных инструментов, но ограничивается только базовыми функциями извлечения данных.</p><p><b>Scrapy эффективнее для</b>:</p><ul><li>Парсинга интернет-магазинов с тысячами товаров.</li><li>Регулярного мониторинга цен конкурентов.</li><li>Полноценных парсинг-проектов со сложной логикой обработки.</li></ul><p>Фреймворк используют для масштабного сбора данных. Python Scrapy имеет встроенные механизмы для работы с прокси, управления cookies, организации очередей запросов и конвейерной обработки данных.</p><h2>Продвинутые техники парсинга</h2><p>Динамически загружаемый контент — это проблема при парсинге. Чтобы выгрузить целевой контент со страницы, нужно имитировать действия пользователя. Для этого часто используют <b>Selenium.</b> Библиотека управляет браузером — загружает страницы, выполняет JavaScript и получает доступ к DOM после его изменения.</p><p>При обработке динамического контента учитывайте задержки. JavaScript выполняется асинхронно, поэтому Selenium должен дождаться полной загрузки элементов, прежде чем пытаться с ними взаимодействовать.</p><p>Пример ожидания:</p><p>Еще можно использовать time.sleep, но это менее эффективно — задержка фиксирована и не зависит от скорости загрузки страницы.</p><p>Если контент загружается через AJAX, можно использовать execute_script для проверки состояния загрузки. Например, можно проверить значение переменной JavaScript, которая отслеживает состояние загрузки.</p><p>Когда контент загружается поэтапно, приходится комбинировать ожидания, execute_script и циклы для обработки всех частей динамического контента.</p><h2>Работа с API</h2><p>Многие сайты предоставляют API для получения данных. Это предпочтительный способ парсинга на Python. Сбор данных через API:</p><ul><li>не нагружает сервер излишними запросами;</li><li>предоставляет данные в структурированном виде;</li><li>обычно имеет официальную документацию.</li></ul><p>Для работы с API в Python есть библиотека requests.</p><p>Большинство API имеют ограничения на количество запросов. Для их соблюдения нужно добавлять задержки.</p><h2>Использование прокси и обход блокировок</h2><p>Прокси помогают обходить блокировки, которые сайты применяют для защиты от парсинга — не всем нравится, когда их контент собирают в базы. Если сайт блокирует ваш IP-адрес из-за частых запросов, использование прокси позволит продолжить работу под другим IP.</p><p>В Python для работы с прокси нужно импортировать библиотеки requests и urllib. Достаточно указать адрес прокси в параметрах запроса.</p><p>Пример использования прокси с requests:</p><p>Ваш парсер останется незамеченным, если выполнять подмену User-Agent, ставить задержки между запросами, настроить автоматическое распознавание капчи.</p><p>Если сайт предоставляет API, лучше делать запросы через него — это наиболее безопасный и эффективный способ.</p><h2>Рекомендации по парсингу данных</h2><p>Структура проекта способствует его поддержке, расширению и повторному использованию. Делите большие парсеры на отдельные компоненты по функциональности — один модуль для авторизации, другой для навигации по страницам, третий для извлечения тегов.</p><p>Файлы, полученные при парсинге, также требуют правильной организации хранения и обработки. Выбор формата зависит от объема и структуры данных:</p><ul><li>JSON подходит для иерархических данных и удобен для дальнейшей обработки в Python.</li><li>CSV эффективен для табличных данных и открывается в Excel.</li></ul><p>Для больших объемов информации используйте БД — SQLite для небольших проектов, PostgreSQL для масштабных. Создавайте промежуточное хранилище перед финальной записью — это защитит от потери информации при сбоях. Для Data Science — <a href="https://tproger.ru/translations/top-10-python-bibliotek-dlja-data-science">отдельная подборка топ-10 библиотек</a>.</p><p>Задержки между запросами — обязательный элемент парсинга. Базовая рекомендация — выдерживайте паузу 1-3 секунды между запросами. Для высоконагруженных сайтов увеличивайте интервал до 5-10 секунд.</p><p>Дополнительные советы по созданию парсера:</p><ul><li>Реализуйте систему логирования для отслеживания ошибок и прогресса.</li><li>Обрабатывайте сетевые ошибки, делайте повторные попытки с экспоненциальной выдержкой.</li><li>Используйте прокси, User Agent для распределения нагрузки и маскировки запросов.</li><li>Проверяйте работоспособность парсера перед запуском, так как структура сайтов может меняться.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>19-летняя девушка-разработчик ускорила serde_json на 32% и рассказала, как достигла этого</title>
      <link>https://tproger.ru/news/19-letnyaya-devuwka-razrabotchik-uskorila-serde-json-na-32--i-rasskazala--kak-dostigla-etogo</link>
      <comments>https://tproger.ru/news/19-letnyaya-devuwka-razrabotchik-uskorila-serde-json-na-32--i-rasskazala--kak-dostigla-etogo?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/19-letnyaya-devuwka-razrabotchik-uskorila-serde-json-na-32--i-rasskazala--kak-dostigla-etogo</guid>
      <description><![CDATA[<p>Алиса Сиренева нашла узкое место в serde_json и ускорила обработку строк на 32% с помощью SIMD и SWAR. Читайте, как провести оптимизацию Rust-библиотеки.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/19-letnyaya-devuwka-razrabotchik-uskorila-serde-json-na-32--i-rasskazala--kak-dostigla-etogo">19-летняя девушка-разработчик ускорила serde_json на 32% и рассказала, как достигла этого</a>»</p>]]></description>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 27 Aug 2024 07:15:11 GMT</pubDate>
      <content:encoded><![CDATA[<p>Алиса Сиренева — 19-летняя разработчица из Москвы. В своем блоге она <a href="https://purplesyringa.moe/blog/i-sped-up-serde-json-strings-by-20-percent/">опубликовала</a> пост, в котором рассказала, как, работая с библиотекой serde_json — стандартом де-факто для сериализации и десериализации JSON в экосистеме Rust, она заметила значительное замедление при обработке ошибок.</p><p>Это вызвало у нее интерес к анализу и поиску оптимизаций, особенно после использования новой библиотеки #[iex], которая фокусируется на улучшении обработки ошибок.</p><p>Анализ показал, что путь обработки ошибок в serde_json в два раза медленнее успешного, и основной причиной этого стала функция position_of_index, ответственная за определение позиции строки и колонки в случае ошибки.</p><p>19-летняя разработчица Алиса Сиренева из Москвы ускорила популярную Rust-библиотеку serde_json на 32% с помощью SIMD и SWAR-оптимизаций.</p><p>Узкое место нашлось в функции position_of_index — она замедляла путь обработки ошибок в два раза по сравнению с успешным путём.</p><p>Ключевое решение — замена медленного линейного поиска на библиотеку memchr, использующую SIMD-инструкции процессора для ускорения поиска символов.</p><p>Все изменения приняты в основную ветку serde_json и доступны миллионам Rust-проектов по всему миру.</p><h2>Решение через оптимизацию</h2><p>Чтобы устранить узкое место, разработчица предложила заменить функцию position_of_index на более эффективную реализацию с использованием библиотеки memchr, которая задействует SIMD-инструкции для быстрого поиска символов.</p><p>Это привело к значительному ускорению обработки ошибок, практически устранив разницу в скорости между успешным и ошибочным путями. Эта оптимизация была одобрена и принята сообществом разработчиков serde_json.</p><h2>Новые горизонты оптимизации</h2><p>Воодушевленная успехом, девушка продолжила поиск возможностей для улучшений. Ее внимание привлекли циклы, ответственные за парсинг строк, которые также можно было оптимизировать с помощью SIMD и SWAR (SIMD Within A Register).</p><p>Хотя не все предложенные методы показали себя одинаково эффективно, использование SWAR оказалась более продуктивным и привело к значительным улучшениям производительности.</p><p>По итогу идеи, предложенные Алисой, показали прирост скорости работы serde_json до 32% в различных тестах, связанных с обработкой строк.</p><p>Эти изменения существенно повышают производительность библиотеки и положительно сказываются на многих проектах, использующих ее.</p>]]></content:encoded>
    </item>
    <item>
      <title>Selenium: пишем парсер для меняющегося сайта</title>
      <link>https://tproger.ru/articles/selenium-pishem-parser-dlya-menyayushhegosya-sajta</link>
      <comments>https://tproger.ru/articles/selenium-pishem-parser-dlya-menyayushhegosya-sajta?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Лена Капаца]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/selenium-pishem-parser-dlya-menyayushhegosya-sajta</guid>
      <description><![CDATA[<p>Разобрали на примере, как работает Python selenium и настроили бота, который будет отсылать находки в Telegram.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/selenium-pishem-parser-dlya-menyayushhegosya-sajta">Selenium: пишем парсер для меняющегося сайта</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 23 Nov 2023 07:11:33 GMT</pubDate>
      <content:encoded><![CDATA[<p>Перед большинством Python-разработчиков рано или поздно встает вопрос сбора данных из сети. У дата-сайентистов, например, этот навык вообще считается само собой разумеющимся, и трудности освоения парсинговых библиотек принято проскакивать как нечто простое. На деле же легко упереться и в меняющиеся классы, и в необходимость проскочить защиту сайта.</p><p>В этой статье мы разберемся, как обходить защиту в виде меняющихся классов и изучим некоторые нюансы этой популярнейшей библиотеки,</p><h2>Выбираем сайт</h2><p>Для гайда я выбрала ресурс otzivisotrudnikov.ru, поскольку он позволяет не только провести парсинг, но и попробовать сопутствующие действия selenium вроде ожидания появления страницы и нажатия кнопки «Загрузить еще».</p><p>Если вы только осваиваете скрэйперы, к сложным порталам, сопротивляющимся парсингу, пока подступаться не стоит. Среди них — все продукты Яндекса, а также Авито. Некоторые популярные площадки вроде HeadHunter, «ощутив пауков на себе», поступили демократично и создали API для выгрузки данных.</p><h2>Подготовка среды разработки</h2><p>Для начала импортируем необходимые библиотеки:</p><p>Загоняем инструментарий в файл requirements.txt:</p><p>Создаем виртуальное окружение и устанавливаем инструменты:</p><p>Я хочу наладить коллекцию пауков таким образом, чтобы новые отзывы отправлялись мне в Telegram. Для этого предстоит создать бота. Чтобы получить ключ, перейдите по адресу <a href="https://my.telegram.org/apps">my.telegram.org/apps</a>, авторизуйтесь и создайте приложение (<a href="https://core.telegram.org/api/obtaining_api_id">документация</a>). API Key лежит в поле App api_hash:</p><p>Чтобы получить ID чата, добавим туда бота @RawDataBot и запустим командой /start. В ответ он отдаст массив, среди которых есть и идентификатор:</p><p>Это целочисленная переменная, знак минус тоже оставляем:</p><p>Чтобы получить токен, нужно пообщаться с @BotFather — утилитой для создания и настройки ботов. Если у вас пока нет ботов в TG, следуйте этой <a href="https://tproger.ru/articles/kak-sozdat-gpt-bota-v-telegrame">краткой инструкции</a>.</p><p>Когда скрейперов становится слишком много, оптимальным решением будет .env-файл. О работе с этим инструментом можно узнать больше в статье “Using .env Files for Environment Variables in Python Applications”.</p><p>Вы могли заметить, что некоторые сайты защищаются от DDoS-атак с помощью спецсервисов. Selenium умеет обходить такие проверки. В случае сайта «Отзывы сотрудников» достаточно подождать несколько секунд, обычно хватает пяти:</p><p>Зададим полную ссылку на страницу:</p><p>Отзывов много, потому нам потребуется нажать кнопку «Больше». Чтобы это сделать, укажем число нажатий (число страниц пока проверяется вручную):</p><p>Инициируем бота для отправки новых отзывов:</p><p>Теперь настал через самого Selenium. Инициируем экземпляр веб-драйвера и передадим ему целевую ссылку:</p><p>Объявим временные списки, в которых будем хранить тексты отзывов, ссылки на них и дату публикации:</p><p>Отдадим команду selenium выполнять поиск элементов на каждой странице:</p><h2>Как быстрее писать селекторы</h2><p>Выбор элемента в HTML — одна из сложных вещей для новичков в парсинге. Потому попробую упростить вам дальнейшую работу с помощью концепции XPath. Это язык запросов для веб-страниц, и корректность селектора можно проверить в панели разработчика Chrome:</p><ul><li>нажимаем на любом свободном месте на веб-странице «Просмотреть код» (или комбинацией Ctrl + Shift + C / Cmd + Shift + C);</li><li>выбираем наведением мыши один отзыв со всеми интересующими элементами и копируем название класса (col-xs-10);</li><li>нажимаем комбинацию Ctrl + F / Cmd + F прямо в панели разработчика. Откроется поле поиска по селектору;</li><li>набираем //* (отсылает к всей странице на языке XPath), затем [@class=’col-xs-10′];</li></ul><p>Посмотреть, как проверяется селектор, можно на <a href="https://cloud.mail.ru/public/AhMd/E9Q7jq1Vp">видео</a>.</p><p>Записей несколько, потому я использую метод find_elements(). Укажем класс, который предстоит найти:</p><p>Теперь результат хранится в специальном объекте selenium-webdriver.WebElement, и чтобы извлечь из него текст, используется метод text().</p><p>Звездочка, кстати, помогает справляться с меняющимися названиями классов: вы можете подставлять ее аналогично сочетанию (.*) в регулярных выражениях, и в случае "//*[@class='col-*']" она будет цеплять все объекты классов, начинающихся с col-.</p><p>В сниппете ниже я удаляю фразу, которая не нужна в выгрузке заказчикам проекта:</p><p>Теперь выделим тем же образом ссылки, они зашиты в кнопки «Читать полностью отзыв и комментарии» (класс ‘read-more-serm‘):</p><p>Осталось вычленить время создания отзыва:</p><p>Теперь троицу выше превратим в словарь:</p><p>Преобразуем словарь в таблицу методом pd.DataFrame():</p><p>Добавим столбец с автоматическим индексом:</p><p>Сохраним результат в файл.csv:</p><figure><img src="https://media.tproger.ru/user-uploads/79101/2023-11-19/4bb65e36-62f4-4f63-abd4-076515636f2d.png" alt="" /></figure><p>Отправим отзывы по одному в чат Telegram:</p><p>Кстати, параметр parse_mode позволяет подключить HTML-разметку и улучшить читаемость отзыва. Разделы «Список льгот», «Что мне нравится в работодателе» и «Что можно было бы улучшить» были «обернуты» полужирным шрифтом (<b>…</b>):</p><figure><img src="https://media.tproger.ru/user-uploads/79101/2023-11-19/c98ba23e-501a-4dfd-a098-0f74409222bb.png" alt="" /></figure><h2>Заключение</h2><p>Конечно, существуют и low-code решения для сбора данных с веба, однако полную управляемость по-прежнему обеспечивают лишь самописные инструменты вроде selenium и beautifulsoup4. Подспорьем новичкам в этой нелегкой задаче, где структура HTML-документа то и дело меняется, может стать <a href="https://github.com/search?q=selenium%20docker&amp;type=repositories">подборка пауков на GitHub</a>. Добросовестная часть авторов их даже обернула в Docker, а это значит, что процесс деплоя и дотяжки селекторов до актуального состояния займет у вас минимум времени.</p><p>Полный код можно посмотреть по <a href="https://gist.github.com/fitwist/734f6c0f49b58bed2d624d28bebfcd37">ссылке</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Bose — фреймворк для создания веб-ботов, который проще Selenium</title>
      <link>https://tproger.ru/articles/bose-framework-wvejcarskij-nozh-dlya-razrabotki-botov</link>
      <comments>https://tproger.ru/articles/bose-framework-wvejcarskij-nozh-dlya-razrabotki-botov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Рафаил Агазода]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/bose-framework-wvejcarskij-nozh-dlya-razrabotki-botov</guid>
      <description><![CDATA[<p>Bose Framework — это улучшенный Selemium, который позволяет быстро и просто настраивать ботов и заниматься быстрой отладкой.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/bose-framework-wvejcarskij-nozh-dlya-razrabotki-botov">Bose — фреймворк для создания веб-ботов, который проще Selenium</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Фреймворки и библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 31 May 2023 09:06:12 GMT</pubDate>
      <content:encoded><![CDATA[<p>Разработка ботов — это сложно.</p><p>Детекторы ботов вроде Cloudflare готовы защищать сайты от наших ботов. Настройка Selenium с помощью ChromeOptions слишком громоздкая, а на Windows становится совсем кошмарной. Отладка ботов через журналы — тоже слишком сложно.</p><p>Как решить эти боли, не жертвуя скоростью и удобством разработки? Попробуйте Bose.</p><p>Bose, как уверяют разработчики фреймворка, — это первая среда разработки ботов, которая максимально упрощает разработку ботов. Фреймворк основан на на Selenium и предлагает ряд функций, упрощающих разработку.</p><h2>Настраиваем Bose</h2><p>Первым делом, скопируем изначальный шаблон.</p><p>Затем перейдите в скачанный каталог, установите зависимости и запустите проект:</p><p>Первый запуск займет некоторое время. Всё потому, что он загружает исполняемый файл драйвера Chrome. Следующие запуски будут гораздо быстрее.</p><h2>Основные особенности Bose Framework</h2><p>Добавляет мощные методы, чтобы сделать работу с Selenium намного проще.</p><p>Применяет лучшие практики, чтобы избежать обнаружения ботов Cloudflare и PerimeterX.</p><p>Сохраняет HTML, снимок экрана и сведения о выполнении для каждой задачи, что упрощает отладку.</p><p>Вспомогательные компоненты для записи очищенных данных в виде файлов JSON, CSV и Excel.</p><p>Автоматически загружает и инициализирует правильный драйвер Chrome.</p><p>Быстро и удобно для разработчиков.</p><h2>Работаем с Bose</h2><p>Допустим, вы хотите начать парсинг веб-сайта. Если бы вы использовали Selenium, вам пришлось бы обрабатывать задачи по открытию и закрытию драйвера следующим образом:</p><p>Однако Bose Framework использует декларативный и структурированный подход. Вам нужно только написать код ниже, а драйвер Bose сам создаст драйвер, передаст его методу run и закроет работу.</p><h2>Конфигурация Bose</h2><p>В Selenium, если вы захотите настроить параметры вроде профиля, пользовательского агента или размера окна, нужно будет написать много кода:</p><p>Bose Framework упрощает конфигурацию, инкапсулируя её в свойстве BrowserConfig:</p><h2>Обработка исключений</h2><p>Исключения — это боль при работе с Selenium.</p><p>В Selenium, если возникает исключение, драйвер автоматически закрывается, оставляя вам только журналы для отладки.</p><p>В Bose, когда в задаче парсинга возникает исключение, браузер остается открытым. Вы можете отслеживать состояние браузера в момент возникновения исключения, что очень помогает при отладке.</p><figure><img src="https://media.tproger.ru/uploads/2023/05/e771a3e1-4faa-41c9-9242-1e29aa37be30.png" alt="" /></figure><h2>Отладка в Bose Framework</h2><p>При веб-скрапинге часто возникают ошибки вроде неправильных селекторов или страниц, которые не загружаются. При отладке в Selenium вам, возможно, придется отсматривать журналы, чтобы найти, какая возникла проблема.</p><p>Bose упрощает отладку, сохраняя информацию о каждом запуске.</p><p>После каждого запуска в задачах создается каталог, содержащий три файла, перечисленных ниже:</p><p>Файл содержит информацию о выполнении задачи: продолжительность выполнения задачи, IP-адрес задачи, пользовательский агент, размер окна и профиль, который использовался для выполнения задачи.</p><p>Это снимок экрана, сделанный до закрытия драйвера.</p><p>Это исходный HTML-код, полученный до закрытия драйвера. Код страницы полезно знать, если селекторам не удалось выбрать элементы.</p><p>В случае, если ваша задача рухнула из-за исключения, Bose сохраняет error.log с ошибкой, из-за которой задача рухнула.</p><h2>Вывод данных</h2><p>После выполнения парсинга веб-страниц нужно сохранить данные в формате JSON или CSV. Как правило, этот процесс подразумевает написание огромного объёма императивного кода:</p><p>Bose упрощает процесс, инкапсулируя данные в модуль вывода для чтения и записи данных. Просто метод write для файла, который вы хотите сохранить.</p><p>Все данные будут сохранены в папке output/:</p><h2>Локальное хранилище</h2><p>В современных браузерах есть локальный модуль хранения, и Bose перенял эту концепцию.</p><p>Вы можете импортировать объект LocalStorage из Bose, чтобы сохранять данные при запуске браузера, что чрезвычайно полезно при очистке больших объемов данных.</p><p>Данные хранятся в файле local_storage.json в корневом каталоге проекта. Вот как можно его использовать:</p><h2>Другие возможности</h2><p>Драйвер, полученный при запуске задачи — это расширенная версия Selenium, в которую добавлены мощные методы, упрощающие работу.</p><p>Вот некоторые из популярных методов, добавленных в драйвер:</p><figure><img src="https://media.tproger.ru/uploads/2023/05/8a32df2f-06fa-4e94-a2a9-33640be6fccd.png" alt="" /></figure><h2>Заключение</h2><p>Bose — отличный фреймворк, упрощающий скучные части Selenium и парсинга веб-страниц.</p><p>Желаем вам удачи и счастливой разработки ботов с помощью Bose Framework!</p>]]></content:encoded>
    </item>
    <item>
      <title>Скрапинг с Goutte (crawler). Парсинг сайтов с использованием библиотеки Goutte</title>
      <link>https://tproger.ru/articles/skraping-s-goutte-crawler-parsing-sajtov-s-ispolzovaniem-biblioteki-goutte</link>
      <comments>https://tproger.ru/articles/skraping-s-goutte-crawler-parsing-sajtov-s-ispolzovaniem-biblioteki-goutte?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Prog-Time]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/skraping-s-goutte-crawler-parsing-sajtov-s-ispolzovaniem-biblioteki-goutte</guid>
      <description><![CDATA[<p>Показываем PHP-библиотеку для парсинга (скрапинга) сайтов. Вы сможете забирать любую информацию со стороннего сайта и отправлять формы.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/skraping-s-goutte-crawler-parsing-sajtov-s-ispolzovaniem-biblioteki-goutte">Скрапинг с Goutte (crawler). Парсинг сайтов с использованием библиотеки Goutte</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 12 Apr 2022 14:55:53 GMT</pubDate>
      <content:encoded><![CDATA[<p>В новой записи я вам покажу PHP библиотеку для парсинга (скрапинга) сайтов. С помощью данной библиотеки вы сможете забирать любую информацию со стороннего сайта, переходить по ссылкам, автоматически отправлять формы.</p><h3>Подключение библиотеки Goutte и создание запроса на сайт</h3><p>В качестве примера я буду использовать свой сайт. В самом начале нужно сделать запрос на главную страницу, далее мы будем забирать с неё элементы, поэтому код ниже будет использоваться в каждом запросе, просто я его не буду дублировать.</p><h3>Получение текстовой информации с помощью Goutte</h3><p>Используя метод filter вы можете указать селектор для выборки элементов. Так как на данной странице используется несколько элементов с классом home_heading_post мы будем использовать метод each.</p><h3>Получение атрибута href ссылки</h3><h3>Получение атрибута src изображения</h3><h3>Фильтрация выборки (выборка элементов через один)</h3><p>Используйте метод reduce для указания функции для фильтрации выборки. В моём примере указана функция которая задаёт порядок «через 1» и “каждый десятый элемент”.</p><h3>Получение элемента указанного порядка</h3><p>С помощью метода eq вы можете указать номер элемента. Нумерация идёт с 0, поэтому в моём примере и мы получим 4 элемент с классом “home_heading_post”.</p><h3>Получение первого и последнего элемента</h3><p>first() — возвращаем первый элемент.<br />last() — возвращает последний элемент.</p><h3>Получение соседнего элемента на уровне в дереве DOM</h3><p>siblings() — возвращает соседние элементы в дереве DOM.</p><h3>Получение ссылки по тексту и нажатие на ссылку</h3><p>С помощью метода selectLink() получаем ссылку, в качестве параметра передадим текст внутри ссылки.</p><p>С помощью метода link() переходим по ссылке и получаем новую страницу.</p><p>С помощью метода getUri() получаем URI ссылки.</p><h3>Получение объекта изображения</h3><h3>Получение дочерних элементов</h3><h3>Отправка формы с помощью Goutte</h3>]]></content:encoded>
    </item>
    <item>
      <title>Какие проблемы решают мобильные прокси</title>
      <link>https://tproger.ru/articles/kakie-problemy-reshajut-mobilnye-proksi</link>
      <comments>https://tproger.ru/articles/kakie-problemy-reshajut-mobilnye-proksi?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Alina Koval]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kakie-problemy-reshajut-mobilnye-proksi</guid>
      <description><![CDATA[<p>Как обмануть алгоритмы социальных сетей, не улетать в бан при работе с несколькими аккаунтами и безопасно парсить сайты с помощью проксей.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kakie-problemy-reshajut-mobilnye-proksi">Какие проблемы решают мобильные прокси</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[SEO]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Гостевая публикация]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 25 Nov 2021 14:07:07 GMT</pubDate>
      <content:encoded><![CDATA[<p>В этой статье поговорим об актуальном: как обмануть алгоритмы социальных сетей, не улетать в бан при работе с несколькими аккаунтами и безопасно парсить сайты с помощью проксей.</p><p>Прокси-сервер — это программно-технический комплекс, который маршрутизирует через себя весь трафик и делает подмену IP. Прокси получает сигнал от устройства, меняет его на другой адрес и передает далее в глобальную сеть.</p><h2>Виды прокси</h2><p>Обычные (серверные или ЦОД) — это статические адреса. Такие адреса не совсем надёжны, поскольку, как только целевой сервер определит ваш IP как «недобросовестный», он его заблокирует. Такие прокси приходится покупать пачками и постоянно менять.</p><p>Резидентные — это адреса реальных интернет-провайдеров, к которым вы получаете доступ. Они могут быть статическими или обратного подключения, которые меняют адрес самостоятельно спустя время. C такими прокси отслеживать трафик становится труднее.</p><p>Мобильные — это адреса реальных мобильных операторов. Оплачивая такие прокси, вы получаете доступ к полному пулу адресов, которые можно использовать в работе. Мобильные прокси наиболее надёжные, поскольку подходят для широкого круга задач, обеспечивают полную анонимность работы в сети и практически не банятся, в отличии от обычных прокси. Так как эти адреса принадлежат мобильным операторам, здесь очень легко «потеряться» среди обычных пользователей.</p><h2>Кто и зачем использует мобильные прокси?</h2><p>Маркетологи — для охвата большей аудитории при продвижении товаров или услуг. К примеру, у маркетолога есть несколько аккаунтов в популярной соцсети, которые он планирует продвигать. Для того, чтобы обеспечить регулярный постинг, ответы на комментарии и другую активность, необходимо подключить страницы к сторонним сервисам. Для этих целей понадобятся прокси, которые защитят аккаунт и снизят риск бана. Без проксей аккаунт продвигать сложно, поскольку входы с разных устройств и различная активность будут для социальной сети подозрительными.</p><p>SEO-специалисты. При парсинге, сборе семантического ядра и работе с большими объёмами данных не обойтись без прокси. В этом случае использование адресов имеет обязательный, а не рекомендательный характер. Чем больше хотите парсить — тем больше проксей необходимо. Используя несколько адресов вы уменьшите процент подозрения к вам от поисковой системы. Адреса будут равномерно распределять запросы с разных IP.<br />Выбирать для работы лучше приватные — это пул адресов выделенных для вас, которые обеспечит анонимность и стабильную работу приложений, например таких как Key Kollector.</p><p>Арбитражники, которым необходимы прокси для работы с разными источниками трафика. В арбитраже трафика прокси используются в таких целях:</p><ul><li>Фарм аккаунтов и запуск кампаний с мультиаккаунта. Прокси в таком случае помогают обойти ограничения и продлить жизнь созданным страницам.</li><li>Накрутка. Для того, чтобы увеличивать просмотры, лайки и подписчиков, необходимо обойти алгоритмы платформ. В этом также помогают мобильные прокси.</li><li>Регистрация нескольких аккаунтов. Система не заподозрит вас в умышленном увеличении страниц, если к аккаунтам будут подключены прокси.</li><li>Разработчикам ПО. Когда необходима раскрутка и запуск собственных программ, без использования проксей не обойтись. Они помогают обойти проверки от серверов-источников.</li></ul><h2>Почему лучше использовать мобильные прокси?</h2><ol><li>Полная анонимность в сети — мобильные прокси полностью скрывают ваш адрес.</li><li>Защита аккаунта. Никакие данные с вашего устройства не передаются, когда вы используете такие прокси.</li><li>Динамическая смена адреса. За счёт того, что он меняется самостоятельно спустя определенное время, вы можете работать с несколькими аккаунтами одновременно. Это особенно актуально для арбитражников и таргетологов.</li><li>Низкий риск бана. Ни одной площадке не выгодно накладывать ограничения, из-за которых могут пострадать множество обычных пользователей мобильного оператора. Когда сервер получает множество запросов с одного IP-адреса, он понимает, что это никак не связано со спамом, а свидетельствует об обычной деятельности, поэтому ограничений такие прокси практически не имеют.</li></ol><h2>Какие действия целевой сервер может посчитать подозрительными?</h2><ul><li>часовой пояс аккаунта отличается от часового пояса адреса;</li><li>смена адреса слишком быстрая;</li><li>отпечаток ОС не соответствует тому устройству, с которого были совершены действия пользователя.</li></ul><p>В случае, если сервер увидит подозрительные действия, заблокируется сам аккаунт, но не адрес мобильного оператора. Чтобы избежать такой ситуации, важно использовать те прокси, которые работают по алгоритмам обычного пользователя.</p><p>Используя мобильные прокси, вам не нужно переживать о том, что целевой сервер заблокирует вас за выполнения рутинных рабочих задач.</p><h2>Виды мобильных прокси</h2><p>Разделяются прокси по операторам и стандартам связи.</p><p>Операторы: Мегафон, Билайн и прочие.</p><p>Стандарты связи: 3G, 4G/LTE. Разница заключается в скорости загрузки. Выбирать прокси стоит в зависимости от необходимых задач, которые нужно решить.</p><p>Для сложных задач и больших объёмов данных (парсинг) подойдёт 4G, это более распространённый вид проксей.</p><p>Мобильные прокси можно купить на <a href="https://trafficcardinal.com/post/luchshiie-siervisy-mobil-nykh-proksi">специальных сервисах</a> или же создать самостоятельно свою прокси-ферму. Создания собственной фермы имеет свои преимущества, так как такие прокси вы можете использовать для своих собственных задач или же продавать. Как создать собственную прокси-ферму и что для этого нужно — рассказали в этой <a href="https://trafficcardinal.com/post/kak-sdielat-mobil-nyi-proksi">статье</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Парсинг данных онлайн-магазина на C#</title>
      <link>https://tproger.ru/articles/parsing-dannyh-onlajn-magazina-na-c</link>
      <comments>https://tproger.ru/articles/parsing-dannyh-onlajn-magazina-na-c?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Yaroslav Menshikov]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/parsing-dannyh-onlajn-magazina-na-c</guid>
      <description><![CDATA[<p>Парсинг данных интернет-магазина на C# показывает, как получать сведения с веб-портала из кода приложения и обрабатывать результаты.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/parsing-dannyh-onlajn-magazina-na-c">Парсинг данных онлайн-магазина на C#</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Пост пользователя]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 14 Sep 2021 16:37:30 GMT</pubDate>
      <content:encoded><![CDATA[<p>Всем привет! Сегодня мы учимся парсить любой веб-портал из кода нашего приложения. Для парсинга данных используем язык программирования C#. Если ваш любимый язык не C#, то не беда — используя данный подход можно решить задачу парсинга на любом современном языке.</p><p>Итак, ставим задачу.</p><p>Задача: спарсить карточку товара из онлайн магазина baucenter.ru, зная артикул товара.</p><p>Что понадобится ?</p><p>1. Сниффер HTTPS пакетов. Использую <a href="https://www.telerik.com/download/fiddler">Fiddler</a>.</p><p>2. Среда разработки приложения <a href="https://visualstudio.microsoft.com/ru/vs/">Visual Studio 2019</a>.</p><h2>Этап 1. Сбор данных сниффером пакетов</h2><p>Запускаем Fiddler, параллельно открываем браузер и переходим на baucenter.ru. В поле поиска товара вставляем любой известный на данном сайте артикул товара (при открытии любого товара отображается артикул). Использую артикул 416001653.</p><figure><img src="https://media.tproger.ru/uploads/2021/09/Screenshot_1-2.png" alt="" /><figcaption>Результат сбора данных представлен на рисунке 1. Только собранных пакетов будет не 32 как нарисунке, а больше (у меня 320).</figcaption></figure><h2>Этап 2. Фильтрация пакетов</h2><p>Из большого количества собранных пакетов полезными являются единицы, остальные просто засоряют список, тем самым затрудняя понимание того, что нужно сделать.</p><p>Ненужные пакеты — это:</p><ul><li>Пакеты вида Tunnel to …;</li><li>Изображения и шрифты;</li><li>JavaScript файлы;</li><li>CSS файлы;</li><li>Запросы на другие порталы нежели baucenter.ru.</li></ul><p>Удалив ненужное, получаем следующее:</p><figure><img src="https://media.tproger.ru/uploads/2021/09/Screenshot_3.png" alt="" /></figure><p>Рисунок 2. Список отфильтрованных пакетов</p><h2>Этап 3. Анализ отфильтрованных пакетов.</h2><p>Открыв карточку товара с артикулом 416001653 в браузере, видим карточку товара со всеми данными. Нас интересует название товара и цена.</p><p>Название товара: Тумба с раковиной Onika Крит 52 см.</p><p>Цена товара: 3390.</p><p>В Fiddler через поиск по тексту ищем, в каком запросе есть текст с названием товара, ценой и артикулом. В моём случае это запрос №241. Рассмотрим его.</p><figure><img src="https://media.tproger.ru/uploads/2021/09/Screenshot_5.png" alt="" /></figure><p>Обратим внимание, чтобы выполнить данный запрос нужно знать адрес карточки товара https://baucenter.ru/mebel_dlya_vannoy_razmer_50_59sm1217/686594/. А его в данный момент у нас нет.</p><p>Снова через поиск по тексту в Fiddler ищем текст: https://baucenter.ru/mebel_dlya_vannoy_razmer_50_59sm1217/686594/. В моём случае этот текст находится в запросе №217.</p><figure><img src="https://media.tproger.ru/uploads/2021/09/Screenshot_8.png" alt="" /></figure><figure><img src="https://media.tproger.ru/uploads/2021/09/Screenshot_6.png" alt="" /></figure><p>Рассмотрев данный запрос и ответ веб-сайта на данный запрос (рисунки 4 и 5), делаем следующие выводы:</p><ul><li>в HTML-коде ответа на запрос №217 есть ссылка на карточку товара. Зная эту ссылку, мы из кода программы сделаем туда запрос и получим необходимые данные о товаре (название и цену, например);</li><li>для выполнения запроса №217 нужно знать только артикул товара, а он у нас есть («416001653»);</li><li>чтобы получить карточку товара из кода приложения, нужно сделать 2 запроса: POST-запрос на адрес https://baucenter.ru, передав артикул товара, и GET-запрос на полученный адрес из первого запроса.</li></ul><h2>Этап 4. Создать классы GetRequest и PostRequest в приложении</h2><p>Чтобы спарсить данные из приложения, необходимо, чтобы ваше приложение отправило необходимые запросы на веб-портал. Эти запросы должны быть неотличимы от запросов веб-браузера. Для выполнения парсинга данных создадим классы GetRequest и PostRequest.</p><p>Данные классы позволяют выполнять Get и Post запросы на веб-порталы. В конструктор класса передается адрес веб-сайта. В свойства класса передаются стандартные заголовки HTTP запроса: Accept, Host, Data, ContentType, Referer, Useragent. Свойство Proxy служит для установки прокси-сервера, через который будет отправлен запрос.</p><p>Это нужно для удобной проверки выполнения своего кода, передав в это свойство значение прокси-сервера Fiddler (по умолчанию 127.0.0.1:8888). Таким образом, при выполнении запросов из программы вы увидите запросы в Fiddler и сможете легко понять проблему, если она будет.</p><p>Выполнение запроса происходит при вызове метода Run, и передаче в данный метод контейнер куки. Контейнер куки создаёте перед выполнением всех запросов. После выполнения запросов контейнер записывает в себя, полученные от веб-портала куки. Это позволяет выполнять последующие запросы с сохраненными куки-данными.</p><p>Результат выполнения запроса записывается в виде текста в свойство Response.</p><h2>Этап 5. Создание приложения для получения карточки товара</h2><p>Результат выполнения программы представлен на рисунке 6.</p><figure><img src="https://media.tproger.ru/uploads/2021/09/image-4.png" alt="" /></figure><p>Код приложения можно найти <a href="https://github.com/menshikovyaroslav/Parsing">здесь</a>.</p><p>Подробное видео разработки данного проекта здесь:</p>]]></content:encoded>
    </item>
    <item>
      <title>Путешествие в golang regexp</title>
      <link>https://tproger.ru/articles/puteshestvie-v-golang-regexp</link>
      <comments>https://tproger.ru/articles/puteshestvie-v-golang-regexp?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ирина Мамиконян]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/puteshestvie-v-golang-regexp</guid>
      <description><![CDATA[<p>В этой статье мы рассмотрим инструмент, с помощью которого можно прорываться через мусор в тексте — регулярные выражения в Golang.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/puteshestvie-v-golang-regexp">Путешествие в golang regexp</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 13 Aug 2021 12:21:28 GMT</pubDate>
      <content:encoded><![CDATA[<p>Приветствую всех, принадлежащих к клубу «Тыжпрограммист, почини утюг», а также просто интересующихся IT-миром!</p><p>В этой статье мы рассмотрим инструмент, с помощью которого можно прорываться через мусор в тексте.  А также фильтровать контент и названия файлов, отлавливать запрещённые/разрешенные команды, парсить SQL-запросы и выпендриваться перед коллегами. Это регулярные выражения ?</p><p>Все примеры описаны для языка Golang, однако общие принципы, синтаксис самих регулярных выражений применимы и к других языкам программирования.</p><h2>В начале было слово…</h2><p>И слово это – паника. Давайте сперва запомним, как надёжней начинать работу с регулярными выражениями. Рассмотрим простейший пример:</p><p>Запустив сей код легким мановением руки… получим то, что всей душой ненавидят пишущие на golang люди — панику. Дело в том, что MustCompile паникует вместо возврата ошибки, как это сделано, например, в методе Compile из того же пакета.</p><p>Поэтому MustCompile рекомендуется использовать только в тех случаях, когда:</p><ul><li>вы на 100% уверены, что регулярное выражение валидно;</li><li>вы очень хотите упростить код с инициализацией каких-нибудь глобальных переменных.</li></ul><p>В остальных случаях лучше подойдёт вариант с возвратом ошибки.</p><p>Простой пример проверки соответствия (который можно скопировать и поломать):</p><h2>Общая информация</h2><ul><li>Немного общих сведений о регулярных выражениях в Golang (regexp пакет):</li><li>синтаксис RE2 (библиотека регулярок от Google);</li><li>кодировка UTF-8 и классы символов Unicode;</li><li>время выполнения линейно зависимо от размера ввода;</li><li>обратные ссылки не поддерживаются (не думайте об этом, просто положите на полочку в своих «чертогах разума», чуть позже будет объяснение);</li><li>для регулярных выражений лучше использовать (аккуратно, ведь там своя специфика) необработанные строки (raw strings, строки без интерпретации экранированных литералов).</li></ul><p>А теперь приступим к более подробному разбору темы.</p><h3>Простые совпадения</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok1.jpg" alt="" /></figure><p>Простые совпадения не несут в себе никакого тайного смысла. Что написано – то и ищем.</p><p>В дальнейшем в простых примерах будем использовать функции:</p><ul><li>MatchString (проверяет, есть ли в строке вхождения регулярного выражения);</li><li>FindAllString (ищет все последовательные непересекающиеся повторения в<br />строке).</li></ul><p>Регулярные выражения будут выделяться синим цветом, а комментарии — серым для создания качественных нейронных связей в голове читателя.</p><p>Совпадение не полное, в последнем слове лишняя «t».</p><p>«Banana» полностью совпадает со строкой.</p><p>«сat» встречается в строке.</p><p>Находятся два вхождения.</p><h3>Якори границ</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok2.jpg" alt="" /></figure><p>Якори границ позволяют нам делить текст на отдельные слова, явно задавать привязку к началу или концу строки/текста.</p><p>Ищем текст, начинающийся с «I am here», но есть пробел перед «I» – не подходит.</p><p>Ищем строку, состоящую только из кота — но он в середине.</p><p>Ищем кота отдельным словом — находим.</p><p>Ищем что-то, заканчивающееся котом — находим.</p><h3>Классы символов (воин, маг, лучник)</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok3.jpg" alt="" /></figure><p>Классы — это краткая запись перечисления символов, объединённых по какому-либо признаку. Также можно использовать posix классы ([:digit:], [:space:], etc.), если так удобней.</p><p>Ищем вхождение пяти любых символов.</p><p>Ищем вхождения сочетаний: «ow&lt;цифра&gt;&lt;конец слова&gt;» через два символа слова с начала строки, любой символ, затем две НЕ цифры, затем снова «ow», цифра, конец.</p><p>Ищем начало текста, три любых символа, «@_», два символа слова, «D», конец.</p><p>Ищем начало текста, «GO», один пробельный символ, одну цифру, любой символ, две цифры, конец.</p><h3>Специальные символы и escape</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok4.jpg" alt="" /></figure><p>Что нужно знать про специальные символы:</p><ul><li>список спецсимволов: ^ $ * + ? { } [ ] \ | ( )</li><li>их нужно экранировать с помощью `\`, т.е.  `\+` = просто +</li></ul><p>Ищем «I» в начале текста, перенос, «am», перенос, «here», конец текста.</p><p>Ищем «I» (в виде 16-ричного кода символа), в начале текста, перенос, «am», перенос, «here», конец текста.</p><p>Ищем… не «a+b=c», а одно и более повторение «a», «b=c», ибо «+» не экранирован.</p><p>Ищем «a|b=c», символ «|» экранирован, всё в порядке.</p><h3>Повторение (жабное, не жабное)</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok5.jpg" alt="" /></figure><p>Повторения являются, пожалуй, одной из важнейших фич при работе с регулярными выражениями. Как минимум, из-за того, что дают возможность исключать некоторые подвыражения из обязательных (при использовании?). ЖаБным оно стало в связи со случайной опечаткой и осознанием, что так запоминается лучше.</p><p>Ищем все вхождения чисел из одной и более цифр.</p><p>Ищем начало текста, одно повторение «А», от одного до 3 повторений «G», одно и более повторение «А», от 0 до 2 повторений «!».</p><p>Пытаемся найти все вхождения тегов — из-за жадного повторения получаем весь текст как первое вхождение, ибо весь текст также соответствует выражению &lt;.*&gt; — начинается скобкой, дальше имеет 0 и более любых символов, заканчивается скобкой.</p><p>Пытаемся найти все вхождения тегов, используя не жадное повторение — происходит магия, все срабатывает.</p><h3>Квадратные скобки, ИЛИ и НЕ</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok6.jpg" alt="" /></figure><p>Квадратные скобки эквивалентны перечислению (перечислению с отрицанием при использовании ^). Прямая черта | равнозначна набору альтернативных вариантов из слов. Крышечкой ^ обозначается отрицание при использовании внутри квадратных скобок.</p><p>Ищем либо «good», либо «bad», либо один символ в конце текста, не являющийся пробельным, «i», «c» или «e».</p><p>Ищем начало текста, ноль или более (лучше меньше, не жадное повторение) символов из перечня [a, A , u , U , f ,F], «go» или «python», пробел, от одной до трех цифр, точку, одну цифру и конец текста).</p><p>Ищем начало текста, один и более символов из перечня [h, a, H, A], конец текста.</p><p>Ищем начало текста, один и более символов из перечня [h, a, H, A] либо ноль и более символов из перечня [g, o, G, O], конец текста – пустая строка соответствует второму варианту после прямой черты.</p><h3>Группы</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok7.jpg" alt="" /></figure><p>Важное о группах:</p><ul><li>позволяют поместить часть совпадения в отдельный массив;</li><li>квантификатор после скобок группы применяется ко всей группе (под квантификаторами подразумеваются такие товарищи, как: +, *, {min, max}, etc.);</li><li>группа 0 всегда относится ко всему выражению;</li><li>группа 1 — к подвыражению, начинающемуся с “(“ и заканчивающемуся “)”  (и так далее);</li><li>при повторении группы в качестве «группы 1» берется последнее совпадение.</li></ul><p>В примерах некоторые элементы подчеркнуты. Это не баг, это фича, помогающая увидеть, какой элемент в какой список групп попал. Также используется новая функция — FindAllStringSubmatch — возвращающая срез последовательных непересекающихся подсовпадений (совпадений скобочных групп). Вторым параметром в данной функции является ограничение количества найденных подсовпадений (найдется всё, если использовать -1).</p><p>Тема групп совсем не проста, поэтому пробуйте разное, ломайте, дебажьте.</p><p>Ищем все подсовпадения с выражением «любой символ, одна и более цифра», находим три вхождения, в каждом из которых есть группа 0 – всё вхождение целиком – и группа 1 – часть с «одна и более цифра».</p><p>Выделяем год, месяц и день в отдельные группы, ищем (4 цифры), тире, (2 цифры), тире, (2 цифры).  Получаем одно подсовпадение, где группа 0 — вся дата, группа 1 — год, группа 2 — месяц, группа 3 — день.</p><p>Парсинг дат в разных форматах может быть использован в кейсах, когда нам необходимо, например, сделать предположение о возможном содержимом столбцов с данными из стороннего датафрейма и выделить колонки с. временными метками. Реализация без регулярных выражений будет достаточно неудобна.</p><p>Как ни странно, в группе может быть внутренняя подгруппа (а в ней ещё одна…и ещё…). Здесь мы ищем ноль и более (лучше меньше) любых символов, одно и более повторение символа из перечня [a-zA-Z\-0-9], слэш, любой символ, 2 и более повторения символов из перечня [a-zA-Z]. В итоге находим одно вхождение, где группа 0 – все выражение, группа 1, как внешняя, целиком соответствует части «одно и более повторение символа из перечня [a-zA-Z\-0-9], слэш, любой символ, 2 и более повторения символов из перечня [a-zA-Z]», а группа 2 – части «одно и более повторение символа из перечня [a-zA-Z\-0-9]».</p><p>Вспоминается мем (в нём, кстати, есть мааленькая опечатка :), кто отыщет?):</p><figure><img src="https://media.tproger.ru/uploads/2021/07/ris1.jpg" alt="" /></figure><p>С группами, как и с математическим анализом, нужно сесть, поплакать, хорошо разобраться один раз и работать на автомате в дальнейшем…</p><h3>Именованные и необязательные группы</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok8.jpg" alt="" /></figure><p>Еще один факт о регулярных выражениях в Golang:</p><ul><li>обратных ссылок тут нет (!) (запоминание встретившейся группы для повторного использования в том же выражении).</li></ul><p>Иногда этот факт вызывает головную боль.</p><p>В примерах используется новая вспомогательная функция — SubexpNames — позволяющая получить доступ к списку разделённых по названию групп подсовпадений.</p><p>Пытаемся выловить из мусорного текста дату, разделив её на год, месяц, день. В группу Year попадают первые 4 цифры до тире, группу Month — 2 цифры до следующего тире, Day — последние 2 цифры. Доступ к разделенным по названиям групп подсовпадениям получаем при помощи прохождения по re.SubexpNames()</p><p>Ищем go либо Go (группа, которая не попадает в список подсовпадений благодаря ?: после открывающей скобки группы), py либо Py — находим два подсовпадения, где группа 0 — вхождение целиком, группа 1 – вторая группа<br />(которая «py либо Py»).</p><h3>Другие функции для работы с регулярными выражениями</h3><p>Формула функций работы с регулярными выражениями:</p><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok9.jpg" alt="" /></figure><p>Также рассмотрим несколько иных функций на примерах.</p><p>Дальше будет сложно. Слабонервным рекомендуется закрыть статью, отойти от экранов и уехать жить в Лондон (почему бы и нет).</p><h3>Большие примеры с кейсами применения регулярных выражений</h3><h4>Валидация логина:</h4><h4>Фильтрация трафика syslog (привет работающим с logstash и его фильтрами):</h4><h4>Парсинг имен таблиц и баз данных, к которым идет обращение, из SELECT SQL-запроса:</h4><h3>Маленькое заключение</h3><p>Регулярные выражения — достаточно полезная штука при анализе текста, парсинге потокаданных, когда необходимо вытащить оттуда нечто действительно важное…ну и вообще для всякого рода магии ?</p><p>Разбирайтесь, не бойтесь экспериментировать и развлекайтесь!</p>]]></content:encoded>
    </item>
    <item>
      <title>Скрапинг сайта с помощью Python: гайд для новичков</title>
      <link>https://tproger.ru/translations/skraping-sajta-s-pomoshhju-python-gajd-dlja-novichkov</link>
      <comments>https://tproger.ru/translations/skraping-sajta-s-pomoshhju-python-gajd-dlja-novichkov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Олег Борисенков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/skraping-sajta-s-pomoshhju-python-gajd-dlja-novichkov</guid>
      <description><![CDATA[<p>Гайд по созданию HTML-скрапера на Python: отличие скрапинга от API, юридические ограничения и установка библиотек Beautiful Soup и requests.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/skraping-sajta-s-pomoshhju-python-gajd-dlja-novichkov">Скрапинг сайта с помощью Python: гайд для новичков</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 31 May 2021 07:56:43 GMT</pubDate>
      <content:encoded><![CDATA[<p>В этой статье мы разберемся, как создать HTML скрапер на Python, который получает неофициальный доступ к коду сайта и позволяет извлечь необходимые данные.</p><h2>Отличие от вызовов API</h2><p>Альтернативный метод получения данных сайта — вызовы API. Взаимодействие с API — это официально предоставляемый владельцем сайта способ получения данных прямо из БД или обычных файлов. Обычно для этого требуется разрешение владельца сайта и специальный токен. Однако апи доступен не всегда, поэтому скрапинг так привлекателен, однако его законность вызывает вопросы.</p><h2>Юридические соображения</h2><p>Скрапинг может нарушать копирайт или правила использования сайта, особенно когда он используется для получения прибыли, конкурентного преимущества или причинения ущерба (например из-за слишком частых запросов). Однако скрапинг публично доступен и используется для личного использования, академических целей или безвредного некоммерческого использования.<br />Если данные являются платными, требуют регистрации, имеют явную защиту от скрапинга, содержат конфиденциальные данные или личные данные пользователей, то нужно избегать любого из видов скрапинга.</p><h2>Установка Beautiful Soup в Python</h2><p>Beautiful Soup — это Python библиотека для скрапинга данных сайтов через HTML код.<br />Установите последнюю версию библиотеки.</p><p>Чтобы делать запросы, установите requests (библиотеку для отправки HTTP запросов):</p><p>Импортируйте библиотеки в файле Python или Jupiter notebook:</p><p>И несколько стандартных библиотек, которые потребуются для скрапинга на Python:</p><h2>Введение</h2><p>Представьте, что мы хотим произвести скрапинг платформы, содержащей общедоступные объявления о недвижимости. Мы хотим получить цену недвижимости, ее адрес, расстояние, название станции и ближайший до нее тип транспорта для того, чтобы узнать, как цены на недвижимость распределяются в зависимости от доступности общественного транспорта в конкретном городе.</p><p>Предположим, что запрос приведет к странице результатов, которая выглядит следующим образом:<br /><a href="https://media.tproger.ru/uploads/2021/05/searchingData-autoconverted.jpeg"></a><br />Как только мы узнаем, в каких элементах сайта хранятся необходимые данные, нам нужно придумать логику скрапинга, которая позволит нам получить всю нужную информацию из каждого объявления.<br />Нам предстоит ответить на следующие вопросы:</p><ol><li>Как получить одну точку данных для одного свойства (например данные из тега price в первом объявлении)?</li><li>Как получить все точки данных для одного свойства со всей страницы (например все теги price с одной страницы)?</li><li>Как получить все точки данных для одного свойства всех страниц с результатами (например все теги price со всех страниц с результатами)?</li><li>Как устранить несоответствие, когда данные могут быть разных типов (например, есть некоторые объявления, в которых в поле цены указана цена по запросу. В конечном итоге у нас будет столбец, состоящий из числовых и строковых значений, что в нашем случае не позволяет провести анализ)?</li><li>Как лучше извлечь сложную информацию (Например, предположим, что каждое объявление содержит информацию об общественном транспорте, например “0,5 мили до станции метро XY”)?</li></ol><h2>Логика получения одной точки данных</h2><p>Все примеры кода для скрапинга на Python можно найти в Jupiter Notebook файле на <a href="https://github.com/christopherkindl/web-scraper-template">GitHub автора</a>.</p><h3>Запрос кода сайта</h3><p>Во-первых, мы используем поисковый запрос, который мы сделали в браузере в скрипте Python:</p><p>Переменная soup содержит полный HTML-код страницы с результатами поиска.</p><h2>Поиск тегов-свойств</h2><p>Для этого нам потребуется браузер. Некоторые популярные браузеры предлагают удобный способ получения информации о конкретном элементе напрямую. В Google Chrome вы можете выбрать любой элемент сайта и, нажав правой кнопкой, выбрать пункт “Исследовать элемент” . Справа откроется код сайта с выделенным элементом.</p><h2>HTML классы и атрибут id</h2><p>HTML-классы и id в основном используются для ссылки на класс в таблице стилей CSS, чтобы данные могли отображаться согласованным образом.<br />В приведенном выше примере, класс, используемый для получения информации о ценах из одного объявления, также применяется для получения цен из других объявлений (что соответствует основной цели класса).</p><p>Обратите внимание, что HTML-класс также может ссылаться на ценники за пределами раздела объявлений (например, специальные предложения, которые не связаны с поисковым запросом, но все равно отображаются на странице результатов). Однако для целей этой статьи мы фокусируемся только на ценах в объявлениях о недвижимости.<br />Вот почему мы сначала ориентируемся на объявление и ищем HTML-класс только в исходном коде для конкретного объявления:</p><p>Использование .text в конце метода find() позволяет нам возвращать только обычный текст, как показано в браузере. Без .text он вернет весь исходный код строки HTML, на которую ссылается класс:</p><figure><img src="https://media.tproger.ru/uploads/2021/05/outputprice.png" alt="" /></figure><p><br />Важное примечание: нам всегда нужно указывать элемент, в данном случае это p.</p><h2>Логика получения всех точек данных с одной страницы</h2><p>Чтобы получить ценники для всех объявлений, мы применяем метод find.all() вместо find():</p><p>Переменная ads теперь содержит HTML-код для каждого объявления на первой странице результатов в виде списка списков. Этот формат хранения очень полезен, так как он позволяет получить доступ к исходному коду для конкретных объявлений по индексу.</p><p>Чтобы получить все ценники, мы используем словарь для сбора данных:</p><p>Важное примечание: использование идентификатора позволяет находить объявления в словаре:</p><h2>Получение точек данных со всех страниц</h2><p>Обычно результаты поиска либо разбиваются на страницы, либо бесконечно прокручиваются вниз.</p><h3>Вариант 1. Веб-сайт с пагинацией</h3><p>URL-адреса, полученные в результате поискового запроса, обычно содержат информацию о текущем номере страницы.</p><figure><img src="https://media.tproger.ru/uploads/2021/05/paginations.png" alt="" /></figure><p>Важное примечание: номер страницы в URL-адресе обычно становится видимым со второй страницы. Использование базового URL-адреса с дополнительным фрагментом &amp;pn=1 для вызова первой страницы по-прежнему будет работать (в большинстве случаев).</p><p>Применение одного цикла for-loop поверх другого позволяет нам перебирать страницы результатов:</p><h3>Определение последней страницы результатов</h3><p>Вы можете задаться вопросом, как определить последнюю страницу результатов? В большинстве случаев после достижения последней страницы, любой запрос с большим числом, чем фактическое число последней страницы, приведет нас обратно на первую страницу. Следовательно, использование очень большого числа для ожидания завершения сценария не работает. Через некоторое время он начнет собирать повторяющиеся значения.</p><p>Чтобы решить эту проблему, мы будем проверять, есть ли на странице кнопка с такой ссылкой:</p><h3>Вариант 2. Сайт с бесконечным скроллом</h3><p>В таком случае HTML скрапер не сработает. Альтернативные методы мы обсудим в конце статьи.</p><h2>Устранение несогласованности данных</h2><p>Если нам нужно избавиться от ненужных данных в самом начале скрапинга на Python, мы можем использовать обходной метод:</p><h3>Функция для определения аномалий</h3><p>И применить его при сборе данных:</p><h3>Форматирование данных на лету</h3><p>Мы могли заметить, что цена хранится в строке вместе с запятыми с символом валюты. Мы можем исправить это ещё на этапе скрапинга:</p><p>Используем эту функцию:</p><h2>Получение вложенных данных</h2><p>Информация об общественном транспорте имеет вложенную структуру. Нам потребуются данные о расстоянии, названии станции и типе транспорта.</p><h3>Отбор информации по правилам</h3><p>Каждый кусочек данных представлен в виде: число миль, название станции. Используем слово “миль” в качестве разделителя.</p><p>Первоначально переменная transport хранит два списка в списке, поскольку есть две строки информации об общественном транспорте (например, “0,3 мили Слоун-сквер”, “0,5 мили Южный Кенсингтон”). Мы перебираем эти списки, используя len транспорта в качестве значений индекса, и разделяем каждую строку на две переменные: расстояние и станцию.</p><h3>Поиск дополнительных HTML атрибутов для визуальной информации</h3><p>В коде страницы мы можем найти атрибут testid, который указывает на тип общественного транспорта. Он не отображается в браузере, но отвечает за изображение, которое отображается на странице. Для получения этих данных нам нужно использовать класс css-StyledIcon:</p><h2>Преобразование в датафрейм и экспорт в CSV</h2><h3>Когда скрапинг выполнен, все извлеченные данные доступны в словаре словарей.</h3><p>Давайте сначала рассмотрим только одно объявление, чтобы лучше продемонстрировать заключительные шаги трансформации.<br /><a href="https://media.tproger.ru/uploads/2021/05/onead.png"></a>Преобразуем словарь в список списков, чтобы избавиться от вложенности</p><figure><img src="https://media.tproger.ru/uploads/2021/05/listoflist.png" alt="" /></figure><h3>Создаём датафрейм</h3><figure><img src="https://media.tproger.ru/uploads/2021/05/dataframe-autoconverted.jpeg" alt="" /></figure><p>Мы можем экспортировать датафрейм в CSV:</p><p>Преобразование всех объявлений в датафрейм:</p><p>Мы это сделали! Теперь наш скрапер готов к тестированию.</p><h2>Ограничения HTML скрапинга и его альтернативы</h2><p>Этот пример показывает, насколько простым может быть скрапинг HTML на Python в стандартном случае. Для этого не нужно исследовать документацию. Это требует, скорее, творческого мышления, чем опыта веб-разработки.</p><p>Однако HTML скраперы имеют недостатки:</p><ul><li>Можно получить доступ только к информации в HTML-коде, которая загружается непосредственно при вызове URL-адреса. Веб-сайты, которые требуют JavaScript и Ajax для загрузки контента, не будут работать.</li><li>HTML-классы или идентификаторы могут изменяться в связи с обновлениями веб-сайта.</li><li>Может быть легко обнаружен, если запросы кажутся аномальными для веб-сайта (например, очень большое количество запросов в течение короткого промежутка времени).</li></ul><p>Альтернативы:</p><ul><li>Shell скрипты — загружают всю страницу, с помощью регулярных выражений могут обрабатывать html.</li><li>Screen scraper — изображают реального пользователя, используют браузер (Selenium, PhantomJS).</li><li>ПО для скрапинга — рассчитаны на стандартные случаи, не требуют написания кода (webscraper.io).</li><li>Веб сервисы скраперы — не требуют написания кода, хорошо справляются со скрапингом, платные (zyte.com).</li></ul><p>Здесь вы найдёте список <a href="https://tproger.ru/articles/tips-and-libraries-for-web-scraping/">инструментов и библиотек для скрапинга</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Лучшие сервисы для веб скрапинга данных: топ-7</title>
      <link>https://tproger.ru/translations/luchshie-servisy-dlja-veb-skrapinga-dannyh-top-7</link>
      <comments>https://tproger.ru/translations/luchshie-servisy-dlja-veb-skrapinga-dannyh-top-7?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Олег Борисенков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/luchshie-servisy-dlja-veb-skrapinga-dannyh-top-7</guid>
      <description><![CDATA[<p>Что такое веб скрапинг, как применяют собранные данные и какие сервисы позволяют обойтись без написания кода — с оглядкой на иск Facebook.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/luchshie-servisy-dlja-veb-skrapinga-dannyh-top-7">Лучшие сервисы для веб скрапинга данных: топ-7</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 28 Apr 2021 10:10:28 GMT</pubDate>
      <content:encoded><![CDATA[<p>В октябре 2020 года Facebook подал жалобу в федеральный суд США против двух компаний, обвиняемых в использовании двух вредоносных расширений для браузера Chrome. Эти расширения позволяют выполнять скрапинг данных без авторизации в Facebook, Instagram, Twitter, LinkedIn, YouTube и Amazon.</p><p>Оба расширения собирали публичные и непубличные данные пользователей. Компании продавали эти данные, которые затем использовались для маркетинговой разведки.</p><p>В этой статье мы разберемся, как выполнять скрапинг данных легально, и расскажем про семь сервисов для веб скрапинга, которые не требуют написания кода. Если вы хотите выполнять скрапинг самостоятельно, прочитайте <a href="https://tproger.ru/articles/tips-and-libraries-for-web-scraping/">нашу подборку</a> инструментов и библиотек для скрапинга.</p><h2>Что такое скрапинг данных?</h2><p>Скрапинг данных или веб скрапинг – это способ извлечения информации с сайта или приложения (в понятном человеку виде) и сохранение её в таблицу или файл.</p><p>Это не нелегальная техника, однако способы использования этих данных могут быть незаконными. В следующем видео автор статьи получает данные из его профиля на сайте Medium, используя веб скрапер:</p><h2>Как используют эти данные</h2><p>Веб скрапинг имеет широкий спектр применений. Например, маркетологи пользуются им для оптимизации процессов.</p><h3>1. Отслеживание цен</h3><p>Собирая информацию о товарах и их ценах на Amazon и других платформах, вы можете следить за вашими конкурентами и адаптировать свою ценовую политику.</p><h3>2. Рыночная и конкурентная разведка</h3><p>Если вы хотите проникнуть на новый рынок и хотите оценить возможности, анализ данных поможет вам сделать взвешенное и адекватное решение.</p><h3>3. Мониторинг соцсетей</h3><p>YouScan, Brand Analytics и другие платформы для мониторинга соцсетей используют скрапинг.</p><h3>4. Машинное обучение</h3><p>С одной стороны, машинное обучение и AI используются для увеличения производительности скрапинга. С другой стороны, данные, полученные с его помощью, используют в машинном обучении.</p><p>Интернет — это важный источник данных для алгоритмов машинного обучения.</p><h3>5. Модернизация сайтов</h3><p>Компании переносят устаревшие сайты на современные платформы. Для того чтобы быстро и легко экспортировать данные, они могут использовать скрапинг.</p><h3>6. Мониторинг новостей</h3><p>Скрапинг данных из новостных сайтов и блогов позволяет отслеживать интересующие вас темы и экономит время.</p><h3>7. Анализ эффективности контента</h3><p>Блоггеры или создатели контента могут использовать скрапинг для извлечения данных о постах, видео, твитах и т. д. в таблицу, например, как на видео выше.</p><p>Данные в таком формате:</p><ul><li>легко сортируются и редактируются;</li><li>просто добавить в БД;</li><li>доступны для повторного использования;</li><li>можно преобразовать в графики.</li></ul><h2>Сервисы для веб скрапинга</h2><p>Скрапинг требует правильного парсинга исходного кода страницы, рендеринга JavaScript, преобразования данных в читаемый вид и, по необходимости, фильтрации. Поэтому существует множество готовых сервисов для выполнения скрапинга.</p><p>Вот топ-7 инструментов для скрапинга, которые хорошо справляются с этой задачей.</p><h3>1. Octoparse</h3><p><a href="https://www.octoparse.com/">Octoparse</a> — это простой в использовании скрапер для программистов и не только. У него есть бесплатный тарифный план и платная подписка.</p><p>Особенности:</p><ul><li>работает на всех сайтах: с бесконечным скроллом, пагинацией, авторизацией, выпадающими меню, AJAX и т.д.</li><li>сохраняет данные в Excel, CSV, JSON, API или БД.</li><li>данные хранятся в облаке.</li><li>скрапинг по расписанию или в реальном времени.</li><li>автоматическая смена IP для обхода блокировок.</li><li>блокировка рекламы для ускорения загрузки и уменьшения количества HTTP запросов.</li><li>можно использовать XPath и регулярные выражения.</li><li>поддержка Windows и macOS.</li><li>бесплатен для простых проектов, 75$/месяц — стандартный, 209$/месяц — профессиональный и т. д.</li></ul><h3>2. ScrapingBee</h3><p><a href="https://www.scrapingbee.com/">ScrapingBee</a> Api использует «безголовый браузер» и смену прокси. Также имеет API для скрапинга результатов поиска Google.</p><p>Особенности:</p><ul><li>рендеринг JS;</li><li>ротация прокси;</li><li>можно использовать с Google Sheets и браузером Chrome;</li><li>бесплатен до 1000 вызовов API, 29$/месяц — для фрилансеров, 99$/месяц — для бизнеса и т.д.</li></ul><h3>3. ScrapingBot</h3><p><a href="https://www.scraping-bot.io/">ScrapingBot</a> предоставляет несколько API: API для сырого HTML, API для сайтов розничной торговли, API для скрапинга сайтов недвижимости.</p><p>Особенности:</p><ul><li>рендеринг JS (безголовый Chrome);</li><li>качественный прокси;</li><li>до 20 одновременных запросов;</li><li>геотэги;</li><li>аддон Prestashop, интегрирующийся на ваш сайт для мониторинга цен конкурентов;</li><li>бесплатный тариф на 100 кредитов, 47$/месяц для фрилансеров, 120$/месяц для стартапов, 361$/месяц для для бизнеса и т. д.</li></ul><h3>4. scrapestack</h3><p><a href="https://scrapestack.com/">Scrapestack</a> — это REST API для веб скрапинга в реальном времени. Он позволяет собирать данные с сайтов за миллисекунды, используя миллионы прокси и обходя капчу.</p><p>Особенности:</p><ul><li>одновременные API запросы;</li><li>рендеринг JS;</li><li>шифрование HTTPS;</li><li>более 100 геолокаций;</li><li>бесплатный тариф до 1000 запросов, базовый тариф за 19.99$/месяц, профессиональный тариф за 79.99$/месяц и т. д.</li></ul><h3>5. Scraper API</h3><p><a href="https://www.scraperapi.com/">Scraper API</a> работает с прокси, браузерами и капчей. Его легко интегрировать. Нужно только отправить GET запрос к API с вашим API ключом и URL.</p><p>Особенности:</p><ul><li>рендеринг JS;</li><li>геотэги;</li><li>имеет пул резидентных\мобильных прокси для скрапинга цен, результатов поиска, мониторинга соцсетей и т. д.</li><li>1000 вызовов API бесплатно, тариф для хобби — 29$\месяц, 99$\месяц — для стартапов и т. д.</li></ul><h3>6. ParseHub</h3><p><a href="https://www.parsehub.com/">ParseHub</a> — это сервис для веб скрапинга, не требующий навыков программирования.</p><p>Особенности:</p><ul><li>понятный графический интерфейс;</li><li>экспорт данных в Excel, CSV, JSON или доступ через API;</li><li>XPath, регулярные выражения, CSS селекторы;</li><li>бесплатный тариф, стандартный тариф — 149$/месяц и т. д.</li></ul><h3>7. Xtract.io</h3><p><a href="https://www.xtract.io/">Xtract.io</a> — это гибкая платформа, использующая технологии AI, ML и NLP.</p><p>Её можно настроить для скрапинга и структурирования данных сайтов, постов с соцсетях, PDF файлов, текстовых документов, исторических данных и электронной почты.</p><p>Особенности:</p><ul><li>скрапинг данных из каталогов, финансовых данных, данных об аренде, геолокационных данных, данных о компаниях и контактных данных, обзоров и рейтингов.</li><li>преднастроенная система для автоматизации всего процесса извлечения данных;</li><li>очистка и валидация данных по заданным правилам;</li><li>экспорт в JSON, текст, HTML, CSV, TSV и т. д.</li><li>ротация прокси и прохождение капчи для скрапинга данных в реальном времени.</li><li>гибкая ценовая политика.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>С 1 марта в России запретили парсинг общедоступных персональных данных</title>
      <link>https://tproger.ru/news/s-1-marta-v-rossii-zapretili-parsing-obshhedostupnyh-dannyh</link>
      <comments>https://tproger.ru/news/s-1-marta-v-rossii-zapretili-parsing-obshhedostupnyh-dannyh?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/s-1-marta-v-rossii-zapretili-parsing-obshhedostupnyh-dannyh</guid>
      <description><![CDATA[<p>Поправки к закону «О персональных данных» с 1 марта 2021 года запрещают автоматический сбор опубликованных сведений без согласия их владельца.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/s-1-marta-v-rossii-zapretili-parsing-obshhedostupnyh-dannyh">С 1 марта в России запретили парсинг общедоступных персональных данных</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Россия]]></category>
      <category><![CDATA[Персональные данные]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 02 Mar 2021 06:28:10 GMT</pubDate>
      <content:encoded><![CDATA[<p>С 1 марта 2021 года в России вступили в силу поправки к правилам обработки персональных данных, находящихся в открытом доступе. Теперь их парсинг, без согласия хозяина этих самых данных, официально запрещён, <a href="https://habr.com/ru/post/544788/">пишет</a> Хабр.</p><figure><img src="https://media.tproger.ru/uploads/2021/03/1.jpeg" alt="" /><figcaption>Тема настолько неоднозначная, что сложно понять: новый закон это хорошо или плохо</figcaption></figure><p>В обновлённом варианте закона «О персональных данных» появились изменения, в результате которых теперь нельзя «собирать и использовать опубликованные в Интернете сведения об отдельном лице».</p><p>Также под запретом находится и массовое извлечение с последующим использованием персональных данных с сайтов в автоматическом режиме. Проще говоря, парсинг таких данных запрещён на законодательном уровне.</p><p>Правда, есть возможность сохранить право на автоматизированный сбор данных. Для этого необходимо получить согласие «каждого субъекта на такие действия».</p><p>Полный текст нового закона доступен по <a href="http://www.consultant.ru/cons/cgi/online.cgi?req=doc&amp;ts=72330224208444529181617675&amp;cacheid=FF43D6E433CF67F52C8757800B87186A&amp;mode=splus&amp;base=LAW&amp;n=372682&amp;rnd=0.3866103813501989#166z65os6tp">ссылке</a>.</p><p>Источник: <a href="https://habr.com/ru/post/544788/">Хабр</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Инструменты и библиотеки для веб-скрейпинга</title>
      <link>https://tproger.ru/articles/tips-and-libraries-for-web-scraping</link>
      <comments>https://tproger.ru/articles/tips-and-libraries-for-web-scraping?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Типичный программист]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/tips-and-libraries-for-web-scraping</guid>
      <description><![CDATA[<p>Готовые средства для сбора данных с сайтов: онлайн-сервисы и библиотеки для парсинга на Python, JavaScript и Java с разными возможностями.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/tips-and-libraries-for-web-scraping">Инструменты и библиотеки для веб-скрейпинга</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 13 Mar 2020 15:15:19 GMT</pubDate>
      <content:encoded><![CDATA[<p>Автор — Мария Багулина</p><p>Собирать данные с веб-сайтов (то есть заниматься веб-скрейпингом) можно либо через готовый API, либо путём парсинга. Самостоятельно парсить страницы не всегда просто: многие сайты не любят скрейперов и стараются блокировать их. Мы уже <a href="https://tproger.ru/translations/web-scraping-without-getting-blocked/">рассказывали</a>, как этого избежать, а в этой статье рассмотрим готовые инструменты для парсинга, среди которых наиболее популярные онлайн-сервисы и библиотеки для языков Python, JavaScript, Java.</p><h2>Онлайн-сервисы для скрейпинга</h2><p>Готовые веб-интерфейсы обычно избавляют ото всех хлопот, возникающих во время парсинга веб-страниц. Но по этой же причине большинство из них — платные. Среди примеров:</p><p><a href="https://bit.ly/2OJ66Wl">Scraping-Bot</a> — веб-инструмент, хорошо заточенный под анализ интернет-магазинов: можно легко извлекать изображения, наименования, цены, описания, стоимость доставки и прочую информацию.</p><p><a href="https://bit.ly/2NQ9ayT">Scrapeworks</a> — подойдёт тем, кто не знаком с программированием. Позволяет получать данные со страниц в структурированном формате на ваш выбор.</p><p><a href="https://bit.ly/2uBjXGo">Diggernaut</a> — парсер, создаваемый с помощью визуального инструмента или метаязыка. Может читать данные из HTML, XML, JSON, iCal, JS, XLSX, XLS, CSV, Google Spreadsheets.</p><p><a href="https://bit.ly/2OveUOO">ScrapingBee</a> — предоставляет API для работы с Headless Chrome и позволяет сфокусироваться на обработке данных.</p><p><a href="https://bit.ly/2H5pt72">Scraper API</a> — ещё один простой API с большим набором настроек: от заголовков запросов до геолокации IP.</p><h2>Библиотеки для языков программирования</h2><h3>Python</h3><p>Библиотеки на Python предоставляют множество эффективных и быстрых функций для парсинга. Многие из этих инструментов можно подключить к готовому приложению в формате API для создания настраиваемых краулеров. Все перечисленные ниже проекты имеют открытый исходный код.</p><h4>BeautifulSoup</h4><p><a href="https://www.crummy.com/software/BeautifulSoup/">Пакет</a> для анализа документов HTML и XML, преобразующий их в синтаксические деревья. Он использует HTML и XML-парсеры, такие как html5lib и Lxml, чтобы извлекать нужные данные.</p><p>Для поиска конкретного атрибута или текста в необработанном HTML-файле в BeautifulSoup есть удобные функции find(), find_all(), get_text() и другие. Библиотека также автоматически распознаёт кодировки.</p><p>Установить последнюю версию BeautifulSoup можно через easy_install или pip:</p><h4>Selenium</h4><p><a href="https://www.selenium.dev/">Инструмент</a>, который работает как веб-драйвер: открывает браузер, выполняет клики по элементам, заполняет формы, прокручивает страницы и многое другое. Selenium в основном используется для автоматического тестирования веб-приложений, но его вполне можно применять и для скрейпинга. Перед началом работы необходимо установить драйверы для взаимодействия с конкретным браузером, например ChromeDriver для Chrome и Safari Driver для Safari 10.</p><p>Установить Selenium можно через pip:</p><h4>Lxml</h4><p><a href="https://lxml.de/">Библиотека</a> с удобными инструментами для обработки HTML и XML файлов. Работает с XML чуть быстрее, чем Beautiful Soup, при этом используя аналогичный метод создания синтаксических деревьев. Чтобы получить больше функциональности, можно объединить Lxml и Beautiful Soup, так как они совместимы друг с другом. Beautiful Soup использует Lxml как парсер.</p><p>Ключевые преимущества библиотеки — высокая скорость анализа больших документов и страниц, удобная функциональность и простое преобразование исходной информации в типы данных Python.</p><p>Установить Lxml:</p><h3>JavaScript</h3><p>Для JavaScript тоже можно найти готовые библиотеки для парсинга с удобными функциональными API.</p><h4>Cheerio</h4><p>Шустрый <a href="https://cheerio.js.org/">парсер</a>, который создаёт DOM-дерево страницы и позволяет удобно с ним работать. Cheerio анализирует разметку и предоставляет функции для обработки полученных данных.</p><p>API Cheerio будет особенно понятен тем, кто работает с jQuery. Парсер позиционирует себя как инструмент, позволяющей сконцентрироваться на работе с данными, а не на их извлечении.</p><p>Установить Cheerio:</p><h4>Osmosis</h4><p>По функциональности <a href="https://www.npmjs.com/package/osmosis">скрейпер</a> похож на Cheerio, но имеет куда меньше зависимостей. Osmosis написан на Node.js и поддерживает селекторы CSS 3.0 и XPath 1.0. Также он умеет загружать и искать AJAX-контент, записывать логи URL-адресов, редиректов и ошибок, заполнять формы, проходить базовую аутентификацию и многое другое.</p><p>Для наглядности можно посмотреть <a href="https://tproger.ru/translations/web-scraping-node-js/">пример</a> парсинга сайтов с помощью Osmosis.</p><p>Установить парсер:</p><h4>Apify SDK</h4><p><a href="https://github.com/apifytech/apify-js">Библиотека</a> Node.js, которую можно использовать вместе с Chrome Headless и Puppeteer.</p><p>Apify позволяет выполнять глубокий обход всего веб-сайта, используя очередь URL-адресов. Также с ней можно запускать код парсера для множества URL в CSV-файле, не теряя никаких данных при сбое программы.</p><p>Для безопасного скрейпинга Apify использует прокси и отключает распознавание фингерпринта браузера на веб-сайтах.</p><p>Установить Apify SDK:</p><h3>Java</h3><p>В Java реализованы различные инструменты и библиотеки, а также внешние API, которые можно использовать для парсинга.</p><h4>Jsoup</h4><p><a href="https://jsoup.org/">Проект</a> с открытым исходным кодом для извлечения и анализа данных с HTML-страниц. Основные функции в целом не отличаются от тех, что предоставляют другие парсеры. К ним относятся загрузка и анализ HTML-страниц, манипулирование HTML-элементами, поддержка прокси, работа с CSS-селекторами и прочее.</p><p>Jsoup не поддерживает парсинг на основе XPath.</p><p><a href="https://jsoup.org/download">Загрузить Jsoup</a></p><h4>Jaunt</h4><p><a href="https://jaunt-api.com/">Библиотека</a>, которую можно использовать для извлечения данных из HTML-страниц или данных JSON с помощью headless-браузера. Jaunt может выполнять и обрабатывать отдельные HTTP-запросы и ответы, а также взаимодействовать с REST API для извлечения данных.</p><p>В целом функциональность Jaunt похож на Jsoup за исключением того, что вместо CSS-селекторов Jaunt использует собственный синтаксис.</p><p><a href="https://jaunt-api.com/download.htm">Загрузить Jaunt</a></p><h4>HTMLUnit</h4><p><a href="http://htmlunit.sourceforge.net/">Инфраструктура</a>, которая позволяет моделировать события браузера, (щелчки, прокрутка, отправка форм) и поддерживает JavaScript. Это улучшает процесс автоматизации получения и обработки информации. HTMLUnit поддерживает парсинг на основе XPath, в отличие от JSoup. Ещё его можно использовать для модульного тестирования веб-приложений.</p><p><a href="https://sourceforge.net/projects/htmlunit/files/htmlunit/2.37.0/">Загрузить HTMLUnit</a></p><p>Знаете ещё примеры хороших библиотек и инструментов для скрейпинга? Поделитесь ими в комментариях.</p>]]></content:encoded>
    </item>
    <item>
      <title>Безопасный веб-скрейпинг: как извлекать данные с сайтов, чтобы вас не заблокировали</title>
      <link>https://tproger.ru/translations/web-scraping-without-getting-blocked</link>
      <comments>https://tproger.ru/translations/web-scraping-without-getting-blocked?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Типичный программист]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/web-scraping-without-getting-blocked</guid>
      <description><![CDATA[<p>Что такое скрейпинг, как краулер обходит страницы и какие приёмы помогают извлекать данные с сайтов, не попадая под блокировку.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/web-scraping-without-getting-blocked">Безопасный веб-скрейпинг: как извлекать данные с сайтов, чтобы вас не заблокировали</a>»</p>]]></description>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 11 Mar 2020 13:05:23 GMT</pubDate>
      <content:encoded><![CDATA[<p>Автор — Мария Багулина</p><p>Чтобы получить данные с сайтов, используется готовый API, однако он не всегда доступен. Тогда приходится использовать «парсер» веб-страницы — в автоматическом или полуавтоматическом режиме распознавать код и получать данные из необходимых полей. Обходом множества страниц и сайтов занимается ПО, которое обычно называется «краулер».</p><p>Процесс сбора данных с сайтов краулером называется веб-скрейпингом.</p><p>Большинство популярных сайтов активно защищают свои ресурсы от скрейпинга используя распознавание IP-адреса, проверку заголовков HTTP-запросов, CAPTCHA и другие способы. Но скрейперы не отстают от них и придумывают новые стратегии обхода. Вот несколько советов, как скрейпить без блокировок.</p><h2>Задайте случайные интервалы между запросами</h2><p>Ни один реальный человек не станет отправлять запросы на сайт каждую секунду в течение 24 часов — такой сбор информации очень легко обнаружить. Используйте случайные задержки (например около 2–10 секунд), чтобы избежать блокировки. И не отправляйте запросы слишком часто, иначе сканирование сайта будет походить на сетевую атаку.</p><p>Особо щепетильным стоит проверить файл robots.txt (как правило, находится на http://&lt;адрес сайта&gt;/robots.txt). Иногда там можно найти параметр Crawl-delay, который говорит, сколько секунд нужно подождать между запросами, чтобы не вредить работе сервера.</p><figure><img src="https://media.tproger.ru/uploads/2020/03/Veb-skraping-bez-blokirovok.jpg" alt="" /></figure><h2>Установите адекватный User Agent</h2><p>User Agent — HTTP-заголовок, который сообщает посещаемому веб-сайту информацию о вашем браузере. Если не настроить User Agent, вашего краулера будет очень легко обнаружить. Кроме того, сайты иногда блокируют запросы пользовательских агентов от неизвестных браузеров. Поэтому не забудьте установить один из популярных пользовательских агентов (например из этого списка).</p><p>Опытные скрейперы могут попробовать установить свой агент на <a href="https://support.google.com/webmasters/answer/1061943?hl=en">Googlebot User Agent</a> — поисковый робот Google. Большинство веб-сайтов, очевидно, хотят попасть в выдачу Google и пропускают Googlebot.</p><p>Хорошей практикой будет также чередование разных User Agent.</p><h2>Используйте прокси</h2><p>Вряд ли настоящий пользователь сможет запрашивать 20 страниц в секунду на одном и том же сайте. Чтобы «обмануть» веб-сервер, заставьте его думать, что все эти запросы приходят из разных мест. Другими словами, используйте прокси.</p><p>Тут есть множество вариантов, например сервисы <a href="https://smartproxy.com/">SmartProxy</a>, <a href="https://luminati.io/">Luminati Network</a>, <a href="https://blazingseollc.com/">Blazing SEO</a>. Бесплатные прокси не всегда подойдут для таких целей: они часто медленные и ненадёжные. Также можно создать свою прокси-сеть на сервере, например с помощью <a href="https://scrapoxy.io/">Scrapoxy</a> — API с открытым исходным кодом.</p><h2>Добавьте referer</h2><p>Referer — заголовок HTTP-запроса, который даёт понять, с какого сайта вы пришли. Неплохой вариант — сделать так, чтобы он показывал, будто вы перешли из Google:</p><p>Стоит менять referer для веб-сайтов в разных странах: например для России использовать <a href="https://www.google.ru/">https://www.google.ru/</a>, а не <a href="http://www.google.com/">https://www.google.com/</a>. Вместо Google можно подставить адреса соцсетей: Youtube, Facebook, ВКонтакте. Referer поможет сделать так, чтобы запросы выглядели как трафик с того сайта, откуда обычно приходит больше всего посетителей.</p><h2>Используйте headless-браузер</h2><p>Особо хитроумные сайты могут отслеживать веб-шрифты, расширения, файлы cookie, цифровые отпечатки (фингерпринты). Иногда они даже встраивают JavaScript-код, открывающий страницу только после его запуска — так зачастую можно определить, поступает ли запрос из браузера. Для обхода таких ресурсов вам потребуется headless-браузер. Он эмулирует поведение настоящего браузера и поддерживает программное управление. Чаще всего для этих целей выбирают <a href="https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md">Chrome Headless</a>.</p><p>Если ресурс отслеживает цифровой отпечаток браузера, то даже многократная смена IP и очистка cookie не всегда помогают, так как вас всё равно могут узнать по фингерпринту. За частую смену IP при одном и том же отпечатке вполне могут заблокировать, и одна из задач Chrome Headless — не допустить этого.</p><p>Самый простой способ работать с Chrome Headless — использовать фреймворк, который объединяет все его функции в удобный API. Наиболее известные решения можно найти <a href="https://www.scrapingbee.com/blog/web-scraping-without-getting-blocked/">тут</a>. Но некоторые веб-ресурсы пытаются отслеживать и их: идёт постоянная гонка между сайтами, пытающимися обнаружить headless-браузеры, и headless-браузерами, которые выдают себя за настоящие.</p><h2>Подключите программу для решения CAPTCHA</h2><p>Существуют веб-сайты, которые систематически просят вас подтвердить, что вы не робот, с помощью капч. Обычно капчи отображаются только для подозрительных IP-адресов, и с этим помогут прокси. В остальных же случаях используйте автоматический решатель CAPTCHA — скажем, <a href="https://2captcha.com/">2Captcha</a> или AntiCaptcha.</p><figure><img src="https://media.tproger.ru/uploads/2020/03/Veb-skraping-bez-blokirovok-2.jpg" alt="" /></figure><p>Распознаватели чаще всего платные, потому что капчи вручную решают реальные люди. Поэтому стоит понять, оправдают ли затраты поставленную цель.</p><h2>Избегайте honeypot-ловушек</h2><p>«Honeypot» — это фальшивая ссылка, которая невидима для обычного пользователя, но присутствует в HTML-коде. Как только вы начнёте анализировать сайт, honeypot может перенаправить вас на пустые и бесполезные страницы-приманки. Поэтому всегда проверяйте, установлены ли для ссылки CSS-свойства «display: none», «visibility: hidden» или «color: #fff;» (в последнем случае нужно учитывать цвет фона сайта).</p><p>Если вы последуете хотя бы одному совету из этой статьи, ваши шансы быть заблокированным уменьшатся во много раз. Но для верности лучше комбинировать несколько приёмов и всегда следить, чтобы краулер не слишком нагружал чужие веб-серверы.</p>]]></content:encoded>
    </item>
    <item>
      <title>Сервис SimilarWeb открыл личные сообщения некоторых пользователей «ВКонтакте»</title>
      <link>https://tproger.ru/news/vk-api-discloses-private-messages</link>
      <comments>https://tproger.ru/news/vk-api-discloses-private-messages?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Светлана Хачатурян]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/vk-api-discloses-private-messages</guid>
      <description><![CDATA[<p>Исследователь получил через SimilarWeb XML-файлы с переписками 300 пользователей «ВКонтакте» и вложениями; соцсеть заблокировала открытые токены API.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/vk-api-discloses-private-messages">Сервис SimilarWeb открыл личные сообщения некоторых пользователей «ВКонтакте»</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[ВКонтакте]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 06 Mar 2018 19:25:50 GMT</pubDate>
      <content:encoded><![CDATA[<p>UPD 07.03 17:50. Пресс-служба «ВКонтакте» <a href="https://tproger.ru/news/vpn-leak-vkontakte/">сообщила</a>, что причиной утечки сообщений стало «использование ненадежных VPN-сервисов».</p><p>Анонимный исследователь под ником yoga2016 <a href="https://steemit.com/hack/@yoga2016/vk-api-disclose-method-to-read-private-messages">обнаружил</a> уязвимость в API «ВКонтакте», позволяющую свободно извлекать сообщения из личной переписки пользователей. Он сразу же сообщил о находке в службу поддержки, однако ему отказали в выплате средств по программе Bug Bounty.</p><h3>«Маркетинговый шпион»</h3><p>SimilarWeb — это инструмент для отслеживания статистики сайтов из поисковых систем. Yoga2016 использовал сервис для анализа «ВКонтакте» и случайно получил ссылки на XML-файлы, содержащие личные сообщения 300 случайных пользователей.</p><p>Структура запросов выглядит следующим образом:</p><p>Переписки можно было выгрузить, приписав к концу адресного запроса .xml. В файлах содержится разметка с полными текстами сообщений, а также все прикреплённые материалы (фотографии, документы).</p><p>Пресс-служба «ВКонтакте» заявила, что раскрытие личных данных не связано с ошибкой в функционировании сайта. Вероятнее всего, утечка произошла из-за недобросовестных или невнимательных сторонних разработчиков, имеющих доступ к API социальной сети. При этом было отмечено, что пользователи скомпрометированных страниц добровольно дали доступ к своим личным данным в настройках приватности.</p><p>Специалисты «ВКонтакте» уже заблокировали открытые токены и ведут расследование.</p>]]></content:encoded>
    </item>
    <item>
      <title>Опубликовано более полумиллиарда паролей от взломанных учётных записей</title>
      <link>https://tproger.ru/news/half-a-billion-pwned-passwords</link>
      <comments>https://tproger.ru/news/half-a-billion-pwned-passwords?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Светлана Хачатурян]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/half-a-billion-pwned-passwords</guid>
      <description><![CDATA[<p>Трой Хант опубликовал базу из 501 636 842 паролей с 269 сайтов; Pwned Passwords проверяет их через сайт и API для скомпрометированных учётных записей.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/half-a-billion-pwned-passwords">Опубликовано более полумиллиарда паролей от взломанных учётных записей</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 25 Feb 2018 16:00:41 GMT</pubDate>
      <content:encoded><![CDATA[<p>Создатель сервиса для проверки скомпрометированных учётных записей Трой Хант <a href="https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/">опубликовал</a> базу, содержащую 501 636 842 актуальных пользовательских пароля, выуженных из 269 сайтов, включая LinkedIn, MySpace и Badoo.</p><h3>Pwned Passwords</h3><p>Сайт Pwned Passwords предлагает пользователям ввести свой пароль для проверки по накопленной базе данных. По словам Ханта, он не перестаёт удивляться людям, без задней мысли раскрывающим свои рабочие учётные данные сторонним сервисам.</p><figure><img src="https://media.tproger.ru/uploads/2018/02/Searching-for-a-Pwned-Password.jpg" alt="" /></figure><p>У сервиса доступен API, через который можно проверить пароли напрямую через ввод пароля или префикса хэша в адресной строке. Если введённый набор символов найден в базе, сервер возвращает целое число / реальный хэш. В противном случае возвращается сообщение об ошибке.</p><p>Поиск по паролю:</p><figure><img src="https://media.tproger.ru/uploads/2018/02/Snimok-jekrana-2018-02-25-v-17.02.08.png" alt="Pwned Passwords: Сообщение об ошибке: Пароль не найден в базе" /></figure><figure><img src="https://media.tproger.ru/uploads/2018/02/Snimok-jekrana-2018-02-25-v-17.02.29.png" alt="Pwned Passwords: Целое число: пароль найден" /></figure><p>Поиск по префиксу хэша (хэши не чувствительны к регистру и выводятся уже без префикса):</p><figure><img src="https://media.tproger.ru/uploads/2018/02/Range-Search-Results.png" alt="" /></figure><p>Бесплатная база паролей размером в 8,8 ГБ <a href="https://downloads.pwnedpasswords.com/passwords/pwned-passwords-2.0.txt.7z.torrent">открыта</a> для загрузки. Единственное ограничение — пароли в общедоступных данных заменены хэшами <a href="https://ru.wikipedia.org/wiki/SHA-1">SHA-1</a>, чтобы по ним нельзя было идентифицировать пользователей. В таблицах также не содержится длина пароля, но зато у каждого указан счётчик дубликатов, демонстрирующий количество учётных записей, в который этот кодовый набор символов был использован.</p><p>А какие кодовые слова точно найдутся в этой БД — без дополнительных проверок <a href="https://tproger.ru/news/top-100-worst-passwords/">скажет</a> топ-100 худших паролей 2017 года.</p>]]></content:encoded>
    </item>
    <item>
      <title>Получение данных c веб-сайта без API в 3 строки кода на Python</title>
      <link>https://tproger.ru/articles/python-pandas</link>
      <comments>https://tproger.ru/articles/python-pandas?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ярослав Сарницкий]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/python-pandas</guid>
      <description><![CDATA[<p>Pandas 0.20.3 с функцией read_html() извлекает HTML-таблицы со страницы и возвращает их как объект DataFrame — без отдельного API.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/python-pandas">Получение данных c веб-сайта без API в 3 строки кода на Python</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 28 Jul 2017 15:29:45 GMT</pubDate>
      <content:encoded><![CDATA[<p>Рассказываем о том, как можно сэкономить время и нервы при автоматизации процесса получения данных с веб-сайтов без соответствующего API-интерфейса.</p><p>Предположим, что в поисках данных, необходимых для вашего проекта, вы натыкаетесь на такую веб-страницу:<br /><a href="https://media.tproger.ru/uploads/2017/07/1-7.png"></a></p><p>Вот они — все необходимые данные для вашего проекта.</p><p>Но что же делать, если нужные вам данные находятся на сайте, который не предоставляет API для их получения? Конечно же, можно потратить несколько часов и написать обработчик, который получит эти данные и преобразует их в нужный для вашего приложения формат.</p><p>Но есть и более простое решение — это библиотека <a href="http://pandas.pydata.org/">Pandas</a> и ее встроенная функция read_html(), которая предназначена для получения данных с html-страниц.</p><p>Прим. перев.  В данной статье используется версия Pandas 0.20.3</p><p>Да, все настолько просто. Pandas находит html-таблицы на странице и возвращает их как новый объект DataFrame.</p><p>Теперь попробуем указать Pandas, что первая (а точнее нулевая) строка таблицы содержит заголовки столбцов, а также попросим ее сформировать datetime-объект из строки, находящейся в столбце с датой и временем.</p><p>На выходе мы получим следующий результат:</p><p>Теперь все эти данные находятся в DataFrame-объекте. Если же нам нужны данные в формате json, добавим еще одну строчку кода:</p><p>В результате вы получите данные в формате json с правильным форматированием даты по стандарту ISO 8601:</p><p>При желании данные можно сохранить в CSV или XLS:</p><p>Выполните код и откройте файл calls.csv. Он откроется в приложении для работы с таблицами:</p><figure><img src="https://media.tproger.ru/uploads/2017/07/2-3-1024x475.png" alt="" /></figure><p>И, конечно же, Pandas упрощает анализ:</p><p>Статистика запроса:</p><p>Группировку:</p><p>Результат группировки:</p><p>И обработку данных:</p><p>Результат метода unique:</p><p>Теперь вы знаете, как с помощью Python и Pandas можно быстро получить данные с практически любого сайта, не прилагая особых усилий. Освободившееся время предлагаем посвятить чтению других <a href="https://tproger.ru/tag/python/">интересных материалов</a> по Python на нашем сайте.</p>]]></content:encoded>
    </item>
    <item>
      <title>Энтузиаст спарсил 40 тысяч фотографий с сайта знакомств Tinder</title>
      <link>https://tproger.ru/news/scraped-tinder-selfies</link>
      <comments>https://tproger.ru/news/scraped-tinder-selfies?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Егор Мадьяров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/scraped-tinder-selfies</guid>
      <description><![CDATA[<p>Пользователь Kaggle через уязвимость Tinder API скачал фотографии из 40 тысяч аккаунтов в районе залива Сан-Франциско для базы лиц.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/scraped-tinder-selfies">Энтузиаст спарсил 40 тысяч фотографий с сайта знакомств Tinder</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 01 May 2017 10:07:27 GMT</pubDate>
      <content:encoded><![CDATA[<p>У пользователей Tinder есть много причин загружать свои фото на сайт знакомств. Однако передача своей биометрической информации в общедоступную базу данных, предназначенную для обучения сверточных нейронных сетей, вероятно, не входила в их планы при регистрации в этой социальной сети.</p><h3>Что произошло?</h3><p>Пользователь Kaggle, платформы для машинного обучения, которую недавно <a href="https://tproger.ru/news/google-to-buy-kaggle/">приобрела</a> Google, загрузил базу данных лиц, которую он получил, используя уязвимость в Tinder API. Она позволила скачать фотографии с 40 тысяч аккаунтов, принадлежащих пользователям социальной сети, находящимся в области залива Сан-Франциско — по 20 тысяч мужчин и женщин. Многие изображения находились в закрытом доступе.</p><p>База данных <a href="https://web.archive.org/web/20170428131910/https://www.kaggle.com/scolianni/people-of-tinder">«Люди Tinder»</a> (в настоящий момент удалена по требованию Tinder) состоит из 6 скачиваемых zip-файлов. Четыре из них содержат по 10 тысяч фото, а в двух оставшихся собраны по 500 изображений мужчин и женщин. Из некоторых профилей было скачано несколько фотографий, поэтому, вероятно, пострадало меньше 40 тысяч пользователей.</p><p>Кроме того, создатель базы данных, Стюарт Колианни, <a href="https://web.archive.org/web/20171005185237/https://github.com/scoliann/TinderFaceScraper">опубликовал</a> исходный код парсера на GitHub.</p><p>Прим. ред.  Если вы интересуетесь парсингом, прочитайте наше <a href="https://tproger.ru/translations/web-scraping-node-js/">краткое руководство</a> с примерами на Node.js.</p><h3>Зачем он это сделал?</h3><p>Стюарт описывает парсер как «простой скрипт для сохранения фото из профилей Tinder с целью создания базы данных лиц». Также он говорит, что создал эту программу, так как разочаровался в других подобных базах данных. По его словам, эта социальная сеть предоставляет «почти неограниченный доступ к информации, необходимой для создания такой базы данных», а сохранение фото из приложения позволяет «чрезвычайно эффективно собирать такие сведения».</p><p>За три дня базу данных скачали с Kaggle более 300 раз, и, конечно, никто не знает, в каких целях ее будут использовать.</p><h3>Как отреагировал Tinder?</h3><p>Официальный представитель заявил:</p><blockquote>Мы серьезно относимся к безопасности и конфиденциальности информации наших пользователей и обладаем средствами и системами, которые позволяют этим данным оставаться внутри нашей платформы. Стоит отметить, что Tinder — это бесплатная сеть, которой пользуются более чем в 190 странах, и фото из аккаунтов доступны любому зарегистрированному пользователю. Мы постоянно работаем над улучшением качества работы с сетью и внедряем инструменты, которые не позволяют автоматически использовать наш API. В том числе мы выявляем и предотвращаем скачивание данных. Этот человек нарушил условия предоставления услуг (раздел 11), и мы примем соответствующие меры и проведем расследование.</blockquote><p>На данный момент база данных «Люди Tinder» удалена с сайта Kaggle.</p>]]></content:encoded>
    </item>
    <item>
      <title>Парсинг сайтов при помощи Node.js: краткое руководство с примерами</title>
      <link>https://tproger.ru/translations/web-scraping-node-js</link>
      <comments>https://tproger.ru/translations/web-scraping-node-js?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Саша Ушатинская]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/web-scraping-node-js</guid>
      <description><![CDATA[<p>Извлечение данных через API сайтов на Node.js: сбор email-адресов, сводки новостных лент и сравнение цен без загрузки всей страницы целиком.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/web-scraping-node-js">Парсинг сайтов при помощи Node.js: краткое руководство с примерами</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 28 Apr 2017 22:09:09 GMT</pubDate>
      <content:encoded><![CDATA[<p>В этой статье мы познакомимся с парсингом сайтов (web scraping), который можно использовать, например, для пополнения базы email-адресов, создания сводки новостных лент, сравнения цен на один продукт среди нескольких коммерческих ресурсов или извлечения данных из поисковых машин.</p><p>Мы рассмотрим парсинг через API сайтов — такой подход достаточно прост и не требует парсинга всей страницы. Он может не работать, если владельцами ресурса установлены специальные настройки, но в большинстве случаев является неплохим решением.</p><h2>Как это работает?</h2><p>Примерно так: парсер посылает странице get-запрос, получает данные в виде HTML / XML и извлекает их в желаемом формате. Для загрузки файлов через консоль подходит утилита <a href="https://www.gnu.org/software/wget/">WGET</a>, но можно выбрать и любой другой подходящий инструмент на просторах Сети.</p><p>Мы будем использовать написанный для Node.js программный пакет <a href="https://github.com/rchipka/node-osmosis">osmosis</a>, включающий селектор css3/xpath и небольшой http-обработчик. Есть и другие фреймворки вроде <a href="http://webdriver.io/">Webdriver</a> и <a href="http://casperjs.org/">CasperJS</a>, но в данном случае они нам не понадобятся.</p><h2>Настраиваем проект</h2><ol><li>Устанавливаем <a href="https://nodejs.org/">Node.js</a>, поставляемый с менеджером пакетов <a href="https://www.npmjs.com/">npm</a>.</li><li>Создаём новую папку, например, webscrap.</li><li>Переходим в неё: cd webscrap.</li><li>Запускаем из консоли npm init для создания файла package.json.</li><li>Запускаем npm i osmosis --save, чтобы установить пакет для парсинга. Дополнительных зависимостей, кроме как от обработчика и селектора, у него не будет.</li><li>Открываем package.json и создаём новый стартовый скрипт для последующего запуска команды npm start.</li></ol><p>Итоговый package.json будет выглядеть примерно так:</p><p>Создаём файл index.js, в нём будем делать всю работу.</p><h2>Парсим информативный заголовок в Google</h2><p>Это самый базовый пример, с помощью которого мы познакомимся с пакетом и запустим первый Node-скрипт. Помещаем код ниже в файл index.js и запускаем из консоли команду npm start. Она выведет заголовок веб-страницы:</p><p>Разберём, что делают методы. Первый метод get получает веб-страницу в сжатом формате. Следующий метод set выберет элемент заголовка, представленный в виде css3-селектора. Наконец, метод data с console.log обеспечивают вывод. Метод set также принимает строки в качестве аргумента.</p><h2>Получаем релевантные результаты в Google</h2><p>Допустим, мы хотим получить результаты по ключевому слову analytics. Делаем следующее:</p><p>Вот и всё. Этот код извлечёт все соответствующие ключевые слова с первой страницы результатов поиска, поместит их в массив и запишет в лог в консоли. Логика, стоящая за этим, такова: мы сначала анализируем веб-страницу через инструменты разработчика, проверяем блок, в котором находится слово (в данном случае это div #botstuff), и сохраняем его в массив через селектор .card-section .brs_col p a, который найдёт все соответствующие ключевые слова на странице.</p><h2>Увеличиваем количество страниц при релевантном поиске</h2><p>Для этого нужно добавить цепочку вызовов (chaining method), вычислив атрибут href у тега anchor (&lt;a&gt;). Мы ограничимся пятью страницами, чтобы Google не посчитал нас за бот. Если необходимо выставить время между парсингом соседних страниц, добавляем метод .delay(ms) после каждого .paginate().</p><h2>Парсим адреса электронной почты с сайта Shopify</h2><p>В данном случае мы будем собирать email-адреса и названия всех приложений, последовательно перемещаясь с помощью метода .follow, и потом помечать необходимые селекторы в консоли разработчика:</p><p>Код выше можно скомбинировать с методом .paginate, чтобы собрать полностью весь контент (но при этом нас могут и заблокировать).</p><p>Теперь нужно сохранить данные в файле, сделать это можно так (пример модификации кода выше, сохранение в формате json):</p><p>Вот мы и закончили с основами, продолжайте экспериментировать. Но, пожалуйста, не используйте полученные знания во вред другим пользователям Сети.</p>]]></content:encoded>
    </item>
    <item>
      <title>Google приобрела компанию, занимающуюся разработкой чат-ботов</title>
      <link>https://tproger.ru/news/google-bought-apiai</link>
      <comments>https://tproger.ru/news/google-bought-apiai?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Иван Бирюков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/google-bought-apiai</guid>
      <description><![CDATA[<p>Платформу API.ai для общения в приложениях вроде Slack и Facebook Messenger используют более 60 000 разработчиков; сумма сделки не раскрывается.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/google-bought-apiai">Google приобрела компанию, занимающуюся разработкой чат-ботов</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 20 Sep 2016 20:30:13 GMT</pubDate>
      <content:encoded><![CDATA[<p>Вчера Google <a href="https://developers.googleblog.com/2016/09/making-conversational-interfaces-easier-to-build.html">приобрела</a> компанию API.ai, которая занимается разработкой интерфейсов для общения. Платформу компании для создания коммуникационных интерфейсов в приложениях наподобие Slack и Facebook Messenger используют более 60 000 разработчиков. Финансовые подробности сделки не оглашаются.</p><p>Инструменты API.ai упрощают парсинг человеческой письменной речи. Компания предоставляет огромный набор возможностей для распознавания естественного языка, в частности, стандартные пакеты Domains, которые содержат базовые запросы и облегчают дальнейшую работу с ботом. Также API.ai управляет чат-ботом собственной разработки под названием Assistant, которым пользуются более 4 миллионов пользователей.</p><p>Компания Google — не новичок в сфере распознавания естественных языков. Весной она <a href="https://tproger.ru/news/google-amazing-parsey-mcparseface/">выложила</a> в открытый доступ фреймворк для создания систем, распознающих синтаксис языков, а летом запустила <a href="https://cloud.google.com/natural-language/">Cloud Natural Language API</a>.</p><p>Титаны в IT-сфере в последнее время стали уделять большое внимание разработке инструментов для создания чат-ботов: в прошлом году Facebook <a href="https://wit.ai/blog/2015/01/05/wit-ai-facebook">приобрёла</a> компанию Wit.ai, а в прошлое воскресенье Oracle <a href="http://www.computerworld.com/article/3121735/application-development/oracle-is-also-getting-in-on-the-chatbot-revolution.html">представила новые инструменты</a> для создания ботов в большинстве чат-сервисов.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как проверять email адрес на валидность правильно</title>
      <link>https://tproger.ru/translations/validating-email-right</link>
      <comments>https://tproger.ru/translations/validating-email-right?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Пётр Соковых]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/validating-email-right</guid>
      <description><![CDATA[<p>Интуитивное представление о виде почтового адреса подводит: полагаться стоит на спецификацию, а у проверки регулярным выражением есть свои проблемы.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/validating-email-right">Как проверять email адрес на валидность правильно</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 17 Aug 2016 18:44:22 GMT</pubDate>
      <content:encoded><![CDATA[<p>Предположим, у вас есть простая задача — создать форму, которая даст пользователю возможность подписаться на e-mail оповещения. Разумеется, вам необходимо предотвратить ввод в эту форму всякого мусора, при этом не должно получаться так, чтобы валидный адрес вдруг был забракован системой.</p><p>Как же выглядит e-mail адрес? Интуитивно можно предположить, что так:</p><p>Выглядит хорошо, но это совершенно не тот случай, когда стоит доверять интуиции. Доверять следует <a href="https://tools.ietf.org/html/rfc5322">спецификации</a>. А спецификация говорит нам следующее:</p><p>Конечно, и тут можно обойтись с помощью регулярного выражения:</p><p>Но с этим есть несколько проблем:</p><ul><li>Как вы будете проверять правильность этого монстра? Такие регулярные выражения переходят «из уст в уста» на форумах, и каждый добавляет в них функциональность до тех пор, пока работа с выражением становится невозможной. И это именно тот случай.</li><li>Я бы не сказал, что регулярные выражения такой длины эффективнее, чем другие методы. Чем длиннее выражение, тем дольше оно будет компилироваться (сравнение всегда происходит за O(n)).</li><li>С помощью регулярного выражения можно сделать только проверку на соответствие. Выполнить проверку на то, находится ли домен в чёрном списке, у вас уже, увы, не получится.</li></ul><h3>Давайте пойдём другим путём</h3><p>Вот основа нашей проверки:</p><p>А вот диаграмма, описывающая алгоритм, по которому наша программа будет работать:</p><figure><img src="https://media.tproger.ru/uploads/2016/08/emailaddrfsm.png" alt="" /></figure><p>Если вы заметили, что тут не все правила соблюдаются — не волнуйтесь, мы вернёмся к этому позже. Если вы не заметили, и вообще не понимаете, что тут происходит, то сейчас объясню.</p><p>Вершина графа — состояние проверки. Ребро графа — прочитанный символ. Если в результате считывания символа невозможно перейти ни по одному ребру, значит, адрес не валиден. Вот, например, как будет реализована первая часть этого алгоритма:</p><figure><img src="https://media.tproger.ru/uploads/2016/08/simplecountingfsm.png" alt="" /></figure><p>Теперь о проверках, которые мы сделаем, после того, как код пройдёт по этой диаграмме:</p><h3>Собираем всё вместе</h3>]]></content:encoded>
    </item>
    <item>
      <title>Анализ данных выявил, что Трамп-с-iPhone добрее, чем Трамп-на-Android</title>
      <link>https://tproger.ru/news/trump-analysis</link>
      <comments>https://tproger.ru/news/trump-analysis?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Пётр Соковых]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/trump-analysis</guid>
      <description><![CDATA[<p>Дэвид Робинсон заметил: пожелания удачи Трамп пишет с iPhone, а оскорбления — с Android, и выгрузил твиты для анализа библиотекой twitteR.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/trump-analysis">Анализ данных выявил, что Трамп-с-iPhone добрее, чем Трамп-на-Android</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[iPhone]]></category>
      <category><![CDATA[Twitter]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 11 Aug 2016 17:33:09 GMT</pubDate>
      <content:encoded><![CDATA[<p>Программист Дэвид Робинсон в очередной раз листая свою твит-ленту заметил интересный факт — когда Трамп желает удачи олимпийцам, он пишет с iPhone, а когда оскорбляет соперников — с Android. Это породило у Дэвида определённую гипотезу, которая нуждалась в проверке с помощью автоматизированного анализа данных. К счастью, он работает в Stack Overflow в качестве Data Scientist, и может себе позволить этим заняться.</p><figure><img src="https://media.tproger.ru/uploads/2016/08/screen1.png" alt="" /></figure><p>Справедливости ради, стоит отметить, что эту закономерность он заметил далеко не первым, однако раньше всё основывалось лишь на догадках и поверхностном просмотре твитов. Без программистов никуда ?</p><p>Сначала он лёгким движением руки загрузил все твиты Трампа (использя библиотеку <a href="https://cran.r-project.org/web/packages/twitteR/">twitteR</a>):</p><p>Затем очистил данные от незначительного количества постов с веб-интерфейса, iPad и прочих — нас же интересуют только посты с iPhone и Android, верно?</p><p>После этого он решил посмотреть, отличается ли время отправки постов с Android и iPhone:</p><p>Выяснилось, что да, отличается — публикации с Android происходят преимущественно утром, тогда как публикации с iPhone — днём и ранним вечером:</p><figure><img src="https://media.tproger.ru/uploads/2016/08/graph1.png" alt="" /></figure><p>Как ещё можно понять, что с Android и iPhone пишут разные люди? Дэвид заметил, что иногда вместо обычного ретвита сообщений, Трамп копирует текст чужого поста и помещает его в кавычки, вроде этого:</p><figure><img src="https://media.tproger.ru/uploads/2016/08/screen2.png" alt="" /></figure><p>Как выяснилось, подобное форматирование можно встретить только в постах с Android:</p><figure><img src="https://media.tproger.ru/uploads/2016/08/graph2.png" alt="" /></figure><p>С другой стороны, практически все публикации с прикреплёнными ссылками или изображениями отправляются с iPhone (разница в 38 раз):</p><figure><img src="https://media.tproger.ru/uploads/2016/08/graph3.png" alt="" /></figure><p>После того, как точно стало понятно, что с Android и iPhone постят совершенно разные люди, Дэвид решил проанализировать настроение постов. Для этого он собрал наиболее часто встречающиеся слова в твитах аккаунта Трампа и посчитал, с какого аккаунта они чаще отправляются, используя коэффициент, формула которого:</p><figure><img src="https://media.tproger.ru/uploads/2016/08/formula.png" alt="" /></figure><p>Результаты получились достаточно предсказуемые:</p><figure><img src="https://media.tproger.ru/uploads/2016/08/graph4.png" alt="" /></figure><p>На основании этого графика можно сделать несколько выводов:</p><ul><li>С Android не публикуются твиты с хэштегами (за исключением “ретвитов”);</li><li>Слова вроде “присоединяйтесь”, “завтра” и “19 часов” используются преимущественно с iPhone, т.е. iPhone используется для анонса мероприятий;</li><li>Почти все грубые, эмоциональные и оценочные выражения (“dumb”, “crazy”, “weak” и т.п.) публикуются с Android.</li></ul><p>Полный текст исследования вы можете прочитать у Дэвида <a href="http://varianceexplained.org/r/trump-tweets/">в блоге</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Парсинг и обработка веб-страницы на PHP: выбираем лучшую библиотеку</title>
      <link>https://tproger.ru/digest/parse-html-via-php</link>
      <comments>https://tproger.ru/digest/parse-html-via-php?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Тарас Сереванн]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/digest/parse-html-via-php</guid>
      <description><![CDATA[<p>Сравнение популярных способов разобрать сторонний сайт на PHP — от регулярных выражений до готовых библиотек для обработки страниц.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/digest/parse-html-via-php">Парсинг и обработка веб-страницы на PHP: выбираем лучшую библиотеку</a>»</p>]]></description>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Подборки]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 27 Oct 2015 16:07:58 GMT</pubDate>
      <content:encoded><![CDATA[<p>Задача спарсить и обработать необходимую информацию со стороннего сайта встает перед веб-разработчиком довольно часто и по самым разнообразным причинам: таким образом можно заполнять свой проект контентом, динамически подгружать какую-то информацию и так далее.</p><p>В таких случаях перед программистом встает вопрос: какую из десятков библиотек выбрать? В этой статье мы постарались рассмотреть самые популярные варианты и выбрать из них лучший.</p><h3>Регулярные выражения</h3><p>Даже не смотря на то, что «регулярки» — это первое, что приходит на ум, использовать их для настоящих проектов не стоит.</p><p>Да, с простыми задачами регулярные выражения справляются лучше всех, но его использование значительно затрудняется, когда нужно спарсить большой и сложный кусок HTML-кода, который, к тому же, не всегда соответствует какому-то определенному шаблону и вообще может содержать синтаксические ошибки.</p><p>Вместо «допиливания» своего регулярного выражения при каждом малейшем изменении кода рекомендуем использовать инструменты ниже — это и проще, и удобнее, и надежнее.</p><h3>XPath и DOM</h3><p><a href="http://php.net/manual/ru/class.domdocument.php">DOM и XPath</a> не являются библиотеками в привычном смысле этого слова, это стандартные модули, которые встроены в PHP начиная с пятой версии. Именно отсутствие необходимости использовать сторонние решения делает их одними из лучших инструментов для парсинга HTML страниц.</p><p>На первый взгляд может показаться, что низкий порог входа — это не о них, некоторые места и вправду являются весьма сложными. Но это только на первый взгляд: стоит только немного разобраться с синтаксисом и базовыми принципами, как XPath тут же станет для вас инструментом для парсинга номер один.</p><p>Вот, например, код с использованием DOM и XPath, который ищет в разметке все теги и модифицирует их атрибуты src:</p><p>Тем не менее, данный вариант не лишен минусов — для парсинга используется движок, в первую очередь предназначенный для работы с XML, а XML и HTML хоть и являются очень похожими языками, но всё же различаются. Из этого вытекают специфические требования к разметке: например, все HTML теги должны быть закрыты.</p><h3>Simple HTML DOM</h3><p><a href="http://simplehtmldom.sourceforge.net/">Simple HTML DOM</a> — PHP-библиотека, позволяющая парсить HTML-код с помощью удобных jQuery-подобных селекторов.</p><p>Она лишена главного недостатка XPath — библиотека умеет работать даже с невалидным HTML-кодом, что значительно упрощает работу. Вы также забудете о проблемах с кодировкой: все преобразования выполняются автоматически.</p><p>Как и JQuery, Simple HTML DOM умеет искать и фильтровать вложенные элементы, обращаться к их атрибутам и даже выбирать отдельные логические элементы кода, например, комментарии.</p><p>В этом примере сначала подгружается, а потом модифицируется заранее заготовленный HTML-код: во второй строке происходит добавление атрибута class со значением bar  первом попавшемуся элементу div, а в следующей строке мы заменяем текст элемента с id=”world” на foo.</p><p>Несмотря на не самую высокую производительность, по сравнению с другими вариантами, Simple HTML DOM имеет самое большое русскоязычное комьюнити и наибольшую распространенность в рунете — для новичков это делает написание кода с её использованием значительно проще.</p><h3>phpQuery</h3><p>Как и Simple HTML DOM, <a href="https://code.google.com/p/phpquery/">phpQuery</a> является PHP вариантом JQuery, но на этот раз более похожим на своего «старшего javascript-брата».</p><p>Портировано почти всё, что есть в JS-фреймворке: поддержка селекторов, атрибутов, манипуляций, обхода, плагинов, событий (в том числе имитации кликов и т.д.) и даже AJAX. Использовать можно как через PHP, так и через командную строку в виде отдельного приложения.</p><p>Более того, согласно нашим бенчмаркам, phpQuery оказался в 8 (!) раз быстрее Simple HTML DOM.</p><p>Вот небольшой пример на phpQuery, в котором происходит обработка заранее выбранных элементов списка (li):</p><p>Подробную документацию и больше примеров найдете на <a href="https://code.google.com/p/phpquery/">официальной странице в Google Code.</a></p><h3>htmlSQL</h3><p><a href="https://github.com/hxseven/htmlSQL">htmlSQL</a> — экспериментальная PHP библиотека, позволяющая манипулировать HTML-разметкой посредством SQL-подобных запросов.</p><p>Простейший пример, извлекающий атрибуты href и title всех ссылок (элементы a) с классом list:</p><p>Как и с обычными mysql_ функциями, воспользовавшись методами fetch_array() или fetch_objects(), мы можем получить результат выполнения данного запроса в виде привычного ассоциативного массива или объекта.</p><p>Стоит также упомянуть о высоком быстродействии htmlSQL: часто она справляется в несколько раз быстрее phpQuery или того же Simple HTML DOM.</p><p>Тем не менее, для сложных задач вам может не хватить функциональности, а разработка библиотеки давно прекращена. Но даже несмотря на это, она всё ещё представляет интерес для веб-разработчиков: в ряде случаев значительно удобнее использовать язык SQL вместо CSS-селекторов. Особенно когда вы не знаете, что такое CSS-селекторы ?</p><h3>Вывод</h3><p>В своем мини-исследовании мы пришли к выводу, что в большинстве случаев для парсинга лучше использовать библиотеку phpQuery: она быстрая, функциональная и современная.</p><p>С другой стороны, для совсем простых задач логично было бы использовать стандартные модули PHP, такие как XPath, DOM или, на крайний случай, регулярные выражения.</p><h3>Что-то ещё?</h3><p>Для PHP существуют ещё десятки разнообразных библиотек и инструментов для парсинга, но в этой статье мы рассмотрели только самые интересные, функциональные и производительные.</p><p>Подробнее о других способах парсинга средствами PHP можно прочитать в соответствующей <a href="http://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php">теме на StackOverflow</a>.</p><p>Если вы не используете PHP, то можете ознакомится с кратким списком похожих инструментов для других языков программирования:</p><p>C++: <a href="http://htmlcxx.sourceforge.net/">htmlcxx</a>, <a href="http://libxmlplusplus.sourceforge.net/">libxml++</a>;</p><p>Python: <a href="http://lxml.de/">lxml</a>, <a href="http://wiki.python.su/%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D1%86%D0%B8%D0%B8/BeautifulSoup">BeautifulSoup</a>, <a href="https://github.com/html5lib/html5lib-python">html5lib</a>;</p><p>Java: <a href="http://jsoup.org/">JSOUP</a>, <a href="https://web.archive.org/web/20160820235127/http://home.ccil.org:80/~cowan/tagsoup/">TagSoup</a>;</p><p>Ruby: <a href="http://www.nokogiri.org/">Nokogiri</a>, <a href="https://github.com/YorickPeterse/oga">Oga</a>, <a href="http://www.crummy.com/software/RubyfulSoup/">Rubyful Soup</a>;</p><p>Perl: <a href="http://search.cpan.org/~gaas/HTML-Parser-3.71/lib/HTML/TokeParser.pm">HTML::TokeParser</a>, <a href="http://search.cpan.org/dist/HTML-Parser/Parser.pm">HTML::Parser</a>, <a href="http://search.cpan.org/~kwilliams/HTML-SimpleParse-0.12/lib/HTML/SimpleParse.pm">HTML::SimpleParse</a>;</p><p>.NET: Html Agility Pack;</p><p>Swift: <a href="http://www.xmlsoft.org/">libxml 2</a>, <a href="https://github.com/topfunky/hpple">Hpple</a>;</p><p>Ассемблер: <a href="http://tibleiz.net/asm-xml/">AsmXml</a>.</p>]]></content:encoded>
    </item>
  </channel>
</rss>