Scrapling

Скрапинг сайтов со скрытым браузером и обходом Cloudflare.

Метаданные навыка

ИсточникОпциональный (устанавливается по запросу) — установите командой hermes skills install official/research/scrapling
Путьoptional-skills/research/scrapling
Версия1.0.0
АвторFEUAZUR
ЛицензияMIT
Платформыlinux, macos, windows
ТегиWeb Scraping, Browser, Cloudflare, Stealth, Crawling, Spider
Связанные навыкиduckduckgo-search, domain-intel

Справочник: полный SKILL.md

инфо

Ниже — полное определение навыка, которое Hermes Agent загружает при его активации. Именно это агент видит как инструкции, пока навык включён.

Scrapling

Scrapling — фреймворк для веб-скрапинга с обходом антибот-защит, скрытой браузерной автоматизацией и встроенным фреймворком-пауком. Поддерживает три стратегии загрузки (HTTP, динамический JS, стелс/Cloudflare) и полноценный CLI.

Навык предназначен только для образовательных и исследовательских целей. Пользователи обязаны соблюдать местное и международное законодательство о сборе данных и уважать условия использования сайтов.

Когда использовать

  • Скрапинг статических HTML-страниц (быстрее браузерных инструментов)
  • Скрапинг страниц с JS-рендерингом, требующих реального браузера
  • Обход Cloudflare Turnstile или детекторов ботов
  • Обход нескольких страниц с помощью паука
  • Когда встроенный инструмент web_extract не возвращает нужные данные

Установка

pip install "scrapling[all]"
scrapling install

Минимальная установка (только HTTP, без браузера):

pip install scrapling

Только браузерная автоматизация:

pip install "scrapling[fetchers]"
scrapling install

Краткий справочник

ПодходКлассКогда использовать
HTTPFetcher / FetcherSessionСтатические страницы, API, массовые запросы
ДинамическийDynamicFetcher / DynamicSessionJS-рендеринг, SPA
СтелсStealthyFetcher / StealthySessionCloudflare, сайты с антибот-защитой
ПаукSpiderОбход нескольких страниц со следованием по ссылкам

Использование CLI

Извлечение статической страницы

scrapling extract get 'https://example.com' output.md

С CSS-селектором и имитацией браузера:

scrapling extract get 'https://example.com' output.md \
  --css-selector '.content' \
  --impersonate 'chrome'

Извлечение страницы с JS-рендерингом

scrapling extract fetch 'https://example.com' output.md \
  --css-selector '.dynamic-content' \
  --disable-resources \
  --network-idle

Извлечение страницы под защитой Cloudflare

scrapling extract stealthy-fetch 'https://protected-site.com' output.html \
  --solve-cloudflare \
  --block-webrtc \
  --hide-canvas

POST-запрос

scrapling extract post 'https://example.com/api' output.json \
  --json '{"query": "search term"}'

Форматы вывода

Формат определяется расширением файла:

  • .html — сырой HTML
  • .md — конвертируется в Markdown
  • .txt — обычный текст
  • .json / .jsonl — JSON

Python: HTTP-скрапинг

Одиночный запрос

from scrapling.fetchers import Fetcher

page = Fetcher.get('https://quotes.toscrape.com/')
quotes = page.css('.quote .text::text').getall()
for q in quotes:
    print(q)

Сессия (с сохранением cookies)

from scrapling.fetchers import FetcherSession

with FetcherSession(impersonate='chrome') as session:
    page = session.get('https://example.com/', stealthy_headers=True)
    links = page.css('a::attr(href)').getall()
    for link in links[:5]:
        sub = session.get(link)
        print(sub.css('h1::text').get())

POST / PUT / DELETE

page = Fetcher.post('https://api.example.com/data', json={"key": "value"})
page = Fetcher.put('https://api.example.com/item/1', data={"name": "updated"})
page = Fetcher.delete('https://api.example.com/item/1')

Через прокси

page = Fetcher.get('https://example.com', proxy='http://user:pass@proxy:8080')

Python: динамические страницы (JS-рендеринг)

Для страниц, требующих выполнения JavaScript (SPA, lazy-load контент):

from scrapling.fetchers import DynamicFetcher

page = DynamicFetcher.fetch('https://example.com', headless=True)
data = page.css('.js-loaded-content::text').getall()

Ожидание конкретного элемента

page = DynamicFetcher.fetch(
    'https://example.com',
    wait_selector=('.results', 'visible'),
    network_idle=True,
)

Отключение ресурсов для ускорения

Блокирует шрифты, изображения, медиа, стили (~25% быстрее):

from scrapling.fetchers import DynamicSession

with DynamicSession(headless=True, disable_resources=True, network_idle=True) as session:
    page = session.fetch('https://example.com')
    items = page.css('.item::text').getall()

Собственная автоматизация страницы

from playwright.sync_api import Page
from scrapling.fetchers import DynamicFetcher

def scroll_and_click(page: Page):
    page.mouse.wheel(0, 3000)
    page.wait_for_timeout(1000)
    page.click('button.load-more')
    page.wait_for_selector('.extra-results')

page = DynamicFetcher.fetch('https://example.com', page_action=scroll_and_click)
results = page.css('.extra-results .item::text').getall()

Python: стелс-режим (обход антибот-защит)

Для сайтов под Cloudflare или с усиленной проверкой fingerprint:

from scrapling.fetchers import StealthyFetcher

page = StealthyFetcher.fetch(
    'https://protected-site.com',
    headless=True,
    solve_cloudflare=True,
    block_webrtc=True,
    hide_canvas=True,
)
content = page.css('.protected-content::text').getall()

Стелс-сессия

from scrapling.fetchers import StealthySession

with StealthySession(headless=True, solve_cloudflare=True) as session:
    page1 = session.fetch('https://protected-site.com/page1')
    page2 = session.fetch('https://protected-site.com/page2')

Выбор элементов

Все фетчеры возвращают объект Selector со следующими методами:

CSS-селекторы

page.css('h1::text').get()              # Текст первого h1
page.css('a::attr(href)').getall()      # Все href ссылок
page.css('.quote .text::text').getall() # Вложенная выборка

XPath

page.xpath('//div[@class="content"]/text()').getall()
page.xpath('//a/@href').getall()

Методы поиска

page.find_all('div', class_='quote')       # По тегу и атрибуту
page.find_by_text('Read more', tag='a')    # По тексту элемента
page.find_by_regex(r'\$\d+\.\d{2}')       # По регулярному выражению

Похожие элементы

Поиск элементов со схожей структурой (удобно для списков товаров и т.п.):

first_product = page.css('.product')[0]
all_similar = first_product.find_similar()

Навигация по DOM

el = page.css('.target')[0]
el.parent                # Родительский элемент
el.children              # Дочерние элементы
el.next_sibling          # Следующий сосед
el.prev_sibling          # Предыдущий сосед

Python: фреймворк-паук

Для обхода нескольких страниц со следованием по ссылкам:

from scrapling.spiders import Spider, Request, Response

class QuotesSpider(Spider):
    name = "quotes"
    start_urls = ["https://quotes.toscrape.com/"]
    concurrent_requests = 10
    download_delay = 1

    async def parse(self, response: Response):
        for quote in response.css('.quote'):
            yield {
                "text": quote.css('.text::text').get(),
                "author": quote.css('.author::text').get(),
                "tags": quote.css('.tag::text').getall(),
            }

        next_page = response.css('.next a::attr(href)').get()
        if next_page:
            yield response.follow(next_page)

result = QuotesSpider().start()
print(f"Scraped {len(result.items)} quotes")
result.items.to_json("quotes.json")

Паук с несколькими сессиями

Маршрутизация запросов к разным типам фетчеров:

from scrapling.fetchers import FetcherSession, AsyncStealthySession

class SmartSpider(Spider):
    name = "smart"
    start_urls = ["https://example.com/"]

    def configure_sessions(self, manager):
        manager.add("fast", FetcherSession(impersonate="chrome"))
        manager.add("stealth", AsyncStealthySession(headless=True), lazy=True)

    async def parse(self, response: Response):
        for link in response.css('a::attr(href)').getall():
            if "protected" in link:
                yield Request(link, sid="stealth")
            else:
                yield Request(link, sid="fast", callback=self.parse)

Пауза и возобновление обхода

spider = QuotesSpider(crawldir="./crawl_checkpoint")
spider.start()  # Ctrl+C — пауза; повторный запуск продолжает с контрольной точки

Типичные ошибки

  • Браузер не установлен: обязательно запустите scrapling install после pip install — без этого DynamicFetcher и StealthyFetcher не будут работать
  • Таймауты: таймаут DynamicFetcher/StealthyFetcher задаётся в миллисекундах (по умолчанию 30000), а Fetcher — в секундах
  • Обход Cloudflare: solve_cloudflare=True добавляет 5–15 секунд к времени загрузки — включайте только когда нужно
  • Потребление ресурсов: StealthyFetcher запускает реальный браузер — ограничивайте количество одновременных запросов
  • Легальность: перед скрапингом всегда проверяйте robots.txt и условия использования сайта. Библиотека предназначена для образовательных и исследовательских целей
  • Версия Python: требуется Python 3.10+
перевод и редактура:

обновлено

⌕ ESC