# Блокировка изображений, шрифтов и медиа в Playwright: меньше трафика

Source: https://ipvolt.com/ru/guides/playwright-block-images-save-bandwidth
Markdown: https://ipvolt.com/ru/guides/playwright-block-images-save-bandwidth.md
Language: ru

[ipvolt — главная](https://ipvolt.com/ru.md) / [Руководства](https://ipvolt.com/ru/guides.md) / Блокировка изображений, шрифтов и медиа в Playwright: меньше трафика

Интеграция
Опубликовано: 2026-10-09
7 мин чтения
Автор: ipvolt

Как блокировать изображения, шрифты и медиа в Playwright через route() на Python и Node.js: для всего контекста или по хостам, с учётом кеша и сервис-воркеров.

## С чего начать

Отменяйте тяжёлые запросы, которые не нужны задаче сбора данных, на каждой странице контекста браузера, а затем измерьте, действительно ли прогон передал меньше байтов.

## Сначала измерьте задачу, потом блокируйте

Изображения, шрифты и видео могут составлять большую часть того, что загружает страница, а многие задачи сбора данных их вообще не читают. Блокировка таких запросов через перехват — распространённый способ сократить прокси-трафик. Поможет ли она вашей задаче, зависит от ваших страниц, поэтому начните с измерения: запустите задачу один раз как есть и запишите, куда уходят байты. [scrapescope](/ru/guides/scraper-bandwidth-report) — бесплатный локальный измеритель с открытым исходным кодом: он показывает байты по хостам и по типам ресурсов для прогона Playwright и моделирует эффект от блокировки изображений, медиа и шрифтов.

В примерах ниже используются Playwright 1.63 и адрес-заполнитель `https://example.com/`. Укажите в TARGET_URL страницу, которую вам разрешено автоматизировать, а настройки и учётные данные прокси держите в собственных параметрах запуска или контекста: чтобы попробовать саму блокировку, они не нужны.

## Блокировка по типу ресурса на Python

Playwright помечает каждый запрос типом ресурса, каким его воспринял движок рендеринга: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest или other. Зарегистрируйте в контексте браузера один маршрут для всех URL и прерывайте три тяжёлых типа; все остальные запросы проходят без изменений.

Сохраните как block_resources.py и запустите python block_resources.py после pip install playwright и playwright install chromium. Контекст также блокирует сервис-воркеры (service workers); причина объясняется ниже.

### block_resources.py · Playwright для Python

```python
import os

from playwright.sync_api import Route, sync_playwright

TARGET_URL = os.environ.get("TARGET_URL", "https://example.com/")
BLOCKED_TYPES = {"image", "media", "font"}


def block_heavy(route: Route) -> None:
    if route.request.resource_type in BLOCKED_TYPES:
        route.abort()
    else:
        route.continue_()


with sync_playwright() as p:
    browser = p.chromium.launch()
    try:
        context = browser.new_context(service_workers="block")
        context.route("**/*", block_heavy)
        page = context.new_page()
        response = page.goto(TARGET_URL, wait_until="load")
        print({"status": response.status if response else None})
        context.close()
    finally:
        browser.close()
```

## Блокировка по типу ресурса на Node.js

Версия для Node.js — тот же маршрут с теми же тремя типами. route.request().resourceType() возвращает тип, route.abort() обрывает запрос до того, как он покинет браузер, а route.continue() отправляет всё остальное как было.

Сохраните как block-resources.mjs и запустите node block-resources.mjs после npm install playwright и npx playwright install chromium.

### block-resources.mjs · Playwright Chromium

```javascript
import { chromium } from 'playwright';

const TARGET_URL = process.env.TARGET_URL ?? 'https://example.com/';
const BLOCKED_TYPES = new Set(['image', 'media', 'font']);

const browser = await chromium.launch();
try {
  const context = await browser.newContext({ serviceWorkers: 'block' });
  await context.route('**/*', route =>
    BLOCKED_TYPES.has(route.request().resourceType()) ? route.abort() : route.continue());
  const page = await context.newPage();
  const response = await page.goto(TARGET_URL, { waitUntil: 'load' });
  console.log({ status: response?.status() });
  await context.close();
} finally {
  await browser.close();
}
```

## Примените правило ко всем страницам контекста браузера

Маршрут на контексте браузера действует на запросы любой страницы этого контекста: страниц, которые вы откроете позже, вторых вкладок и всплывающих окон, которые страница открывает через window.open(). Маршрут на отдельной странице действует только на неё, поэтому всплывающее окно или новая вкладка снова загрузят свои изображения и шрифты. Регистрируйте маршрут контекста до загрузки первой страницы и вынесите его в одну вспомогательную функцию, чтобы все задачи использовали одно правило.

Если запрос подходит под оба маршрута, маршруты страницы имеют приоритет над маршрутами контекста браузера, а если подходят несколько маршрутов страницы, побеждает зарегистрированный последним. Держите один блокирующий маршрут на контекст, чтобы избежать сюрпризов.

### context-wide.mjs · один маршрут для всех страниц

```javascript
import { chromium } from 'playwright';

const TARGET_URL = process.env.TARGET_URL ?? 'https://example.com/';
const BLOCKED_TYPES = new Set(['image', 'media', 'font']);

// One route on the context covers every page the context opens, including
// tabs opened later and popups. Register it before the first page loads.
async function blockHeavyResources(context) {
  await context.route('**/*', route =>
    BLOCKED_TYPES.has(route.request().resourceType()) ? route.abort() : route.continue());
}

const browser = await chromium.launch();
try {
  const context = await browser.newContext({ serviceWorkers: 'block' });
  await blockHeavyResources(context);
  const first = await context.newPage();
  const second = await context.newPage();
  await Promise.all([
    first.goto(TARGET_URL, { waitUntil: 'load' }),
    second.goto(TARGET_URL, { waitUntil: 'load' }),
  ]);
  console.log({ pages: context.pages().length });
  await context.close();
} finally {
  await browser.close();
}
```

## Блокировка отдельных тяжёлых хостов по шаблону URL

Иногда проблема в одном хосте: видео-CDN, рекламном сервере или сервисе шрифтов. route() принимает и шаблон URL, так что можно прерывать всё с этих хостов и не трогать типы ресурсов. Glob-шаблон вроде `https://media.example.net/**` соответствует любому URL на одном хосте; регулярное выражение может перечислить несколько. Хосты ниже — заполнители; настоящие имена берите из своего измерения, а не из универсального списка блокировки.

### block_hosts.py · прерывание названных хостов

```python
import os
import re

from playwright.sync_api import sync_playwright

TARGET_URL = os.environ.get("TARGET_URL", "https://example.com/")
# A glob covers every URL on one host; a regular expression can cover several.
HEAVY_HOST = "https://media.example.net/**"
HEAVY_HOSTS = re.compile(r"^https://(video\.example\.org|fonts\.example\.com)/")

with sync_playwright() as p:
    browser = p.chromium.launch()
    try:
        context = browser.new_context(service_workers="block")
        context.route(HEAVY_HOST, lambda route: route.abort())
        context.route(HEAVY_HOSTS, lambda route: route.abort())
        page = context.new_page()
        response = page.goto(TARGET_URL, wait_until="load")
        print({"status": response.status if response else None})
        context.close()
    finally:
        browser.close()
```

## Маршрутизация отключает HTTP-кеш

В справочнике API Playwright и для page.route(), и для browserContext.route() сказано: "Enabling routing disables http cache." (включение маршрутизации отключает HTTP-кеш). Как только зарегистрирован любой маршрут, таблицы стилей, скрипты и другие повторяющиеся ресурсы, которые браузер обычно взял бы из кеша, загружаются заново для каждой страницы. В задаче, которая загружает много страниц в одном контексте, эта дополнительная передача может свести на нет часть того, что убирает блокировка, или всё целиком. Поэтому теста на одной странице недостаточно: измеряйте весь прогон.

## Блокируйте сервис-воркеры на время перехвата

Запросы, которые обрабатывает сервис-воркер страницы, могут обходить ваши маршруты: справочник API отмечает, что browserContext.route() не перехватывает запросы, перехваченные Service Worker, и рекомендует отключать сервис-воркеры при перехвате запросов, задав serviceWorkers значение 'block'. Это параметр контекста service_workers="block" (Python) и serviceWorkers: 'block' (Node.js) во всех примерах выше. Сайт, который зависит от сервис-воркера, например кеширует содержимое для работы офлайн, может вести себя иначе, когда не может его зарегистрировать.

## Блокировка может изменить поведение страницы

Блокировка изображений, медиа и шрифтов может сломать извлечение данных, изменить поведение страницы или привлечь внимание антибот-систем. Страница может ждать изображение, прежде чем отрисовать данные, которые вы читаете, подгружать контент только после медиа-событий или считать необычным браузер, который никогда не загружает изображения. Проверьте, что извлекаемые значения не изменились после включения маршрута, и держите блокировку в рамках того, что разрешают условия использования сайта.

## Измерьте ещё раз и сравните

Запустите одну и ту же задачу дважды через одного и того же провайдера, один раз без маршрута и один раз с ним, и сравните два прогона. Второй измеренный прогон — это доказательство; модель или оценка — это прогноз. [scrapescope](/ru/guides/scraper-bandwidth-report) умеет сравнивать два отчёта бок о бок в своём просмотрщике, включая байты по хостам и по типам ресурсов, так что видно, что убрал маршрут и что вернул потерянный HTTP-кеш.

## Перед выпуском

- Измерьте задачу один раз без блокировки, прежде чем что-либо менять.
- Регистрируйте маршрут на контексте браузера до загрузки первой страницы.
- Блокируйте сервис-воркеры в параметрах контекста, пока активны маршруты.
- Убедитесь, что извлекаемые значения не изменились после блокировки.
- Сравните второй измеренный прогон через того же провайдера, прежде чем полагаться на изменение.

## Источники и дополнительное чтение

- [Playwright: browserContext.route() (routing notes, v1.63)](https://playwright.dev/docs/api/class-browsercontext#browser-context-route)
- [Playwright: page.route()](https://playwright.dev/docs/api/class-page#page-route)
- [Playwright: request.resourceType()](https://playwright.dev/docs/api/class-request#request-resource-type)
- [Playwright: the serviceWorkers context option](https://playwright.dev/docs/api/class-browser#browser-new-context-option-service-workers)
- [Playwright for Python: browser_context.route()](https://playwright.dev/python/docs/api/class-browsercontext#browser-context-route)
- [Playwright issue 1090: routes and service workers](https://github.com/microsoft/playwright/issues/1090)

## Связанные руководства

- [Настройка прокси в Playwright](https://ipvolt.com/ru/guides/playwright-proxy-setup.md)
- [Ротируемые и sticky-прокси: планируйте непрерывность сессии](https://ipvolt.com/ru/guides/rotating-vs-sticky-proxies.md)
- [Как исправить ERR_TUNNEL_CONNECTION_FAILED в Playwright и Puppeteer](https://ipvolt.com/ru/guides/fix-err-tunnel-connection-failed.md)

## О ipvolt

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

[Читать оригинал на английском](https://ipvolt.com/guides/playwright-block-images-save-bandwidth.md)

## Узнайте, когда откроется доступ.

ipvolt · В разработке

Мы строим прокси-инфраструктуру для разработчиков и команд, работающих с данными. Оставьте email, чтобы получить уведомление, когда ipvolt будет готов.

Одно письмо, когда откроется доступ. Больше ничего.

[Получить ранний доступ](https://ipvolt.com/ru/guides/playwright-block-images-save-bandwidth#waitlist-closing)

[Конфиденциальность](https://ipvolt.com/privacy)

