На Python 3.15.0 большая часть стека для скрапинга ставится из готовых колёс (wheels) и проходит smoke-тест. Всё, что требует brotli или zstandard, на машине без компилятора C не ставится, потому что ни у одного из них нет колеса для 3.15, и это касается даже простого pip install scrapy. Быстрое решение — установить gcc перед pip install (решение 1 ниже) или остаться на Python 3.14, пока brotli не опубликует колёса cp315 (решение 2).
Последняя проверка: 16 октября 2026 года, 10:09 UTC. На тот момент на PyPI всё ещё не было колёс cp315 для brotli 1.2.0 и zstandard 0.25.0. В zope.interface 8.7, вышедшем 15 октября, колёса cp315 появились.
| Пакет | Версия | Колесо cp315 | С компилятором | Без компилятора | Примечания |
|---|---|---|---|---|---|
scrapy | 2.19.0 | чистый Python; нет (brotli 1.2.0) | ставится | ошибка сборки brotli | требует brotli на CPython с 2.18.0 |
requests[socks] | 2.34.2 + PySocks 1.7.1 | чистый Python | ставится | ставится | |
httpx[socks] | 0.28.1 + socksio 1.0.0 | чистый Python | ставится | ставится | |
httpx[brotli] | 0.28.1 | нет (brotli 1.2.0) | ставится | ошибка сборки brotli | httpx brotlicffi ставится без компилятора |
httpx[zstd] | 0.28.1 | нет (zstandard 0.25.0) | ставится | ошибка сборки zstandard | самая долгая сборка |
aiohttp | 3.14.5 | да | ставится | ставится | |
aiohttp[speedups] | 3.14.5 + aiodns 4.0.4 | нет (Brotli 1.2.0) | ставится | ошибка сборки Brotli | aiohttp aiodns brotlicffi ставится |
aiohttp-socks | 0.12.0 | чистый Python | ставится | ставится | |
urllib3[brotli] | 2.8.0 | нет (brotli 1.2.0) | ставится | ошибка сборки brotli | urllib3 brotlicffi ставится |
curl_cffi | 0.16.3 | abi3 | ставится | ставится | |
playwright | 1.64.0 | не зависит от версии | ставится | ставится | браузеры не проверялись |
lxml | 6.1.3 | да | ставится | ставится | |
beautifulsoup4 | 4.15.0 | чистый Python | ставится | ставится | |
parsel | 1.12.1 | чистый Python | ставится | ставится | |
selectolax | 1.0.0 | да | ставится | ставится | 1.0: selectolax.parser выдал ImportError, используйте selectolax.lexbor |
pandas | 3.0.6 + numpy 2.5.4 | да | ставится | ставится | |
pydantic | 2.14.1 + pydantic-core 2.50.1 | pydantic-core: да | ставится | ставится | |
orjson | 3.13.0 | да | ставится | ставится | |
tenacity | 9.2.1 | чистый Python | ставится | ставится |
«С компилятором» и «без компилятора» — это официальный образ python:3.15-slim с gcc и без него. Каждый пакет ставился и через pip, и через uv, и результаты совпали во всех случаях. У чисто питоновского пакета нет скомпилированного кода, поэтому колесо cp315 ему не нужно. Каждая успешная установка прошла свой smoke-тест.
pip install scrapy падает на Python 3.15: Failed building wheel for brotli
В slim-образе pip 26.2.1 останавливается на brotli:
× Building wheel for brotli (pyproject.toml) did not run successfully.
│ exit code: 1
error: [Errno 2] No such file or directory: 'gcc'
ERROR: Failed building wheel for brotli
error: failed-wheel-build-for-install
× Failed to build installable wheels for some pyproject.toml based projects
╰─> brotliuv 0.13.1 падает на том же пакете и показывает цепочку зависимостей:
error: Failed to build `brotli==1.2.0`
cause: The build backend returned an error
hint: `brotli` (v1.2.0) was included because `scrapy` (v2.19.0) depends on `brotli`Цепочка короткая. Scrapy 2.19.0 написан на чистом Python, но требует brotli>=1.2.0; implementation_name != "pypy", так что любая установка на CPython тянет brotli. Это требование появилось в Scrapy 2.18.0 (20 августа 2026 года); в 2.17.0 его не было. У brotli 1.2.0, выпущенного 5 ноября 2025 года, есть колёса для CPython 2.7 и 3.6–3.14 и ничего новее. Без подходящего колеса pip и uv скачивают архив исходников и компилируют расширение _brotli, а для этого нужен gcc. То же происходит с httpx[brotli], aiohttp[speedups] и urllib3[brotli], которым на CPython тоже нужен пакет brotli, и с httpx[zstd], которому нужен zstandard 0.25.0.
Решение 1: добавить компилятор в образ
Этой одной строки в slim-образе хватило для всех пакетов, которые падали:
apt-get update && apt-get install -y --no-install-recommends gcc libc6-devОна установила gcc 14.2.0. После этого pip install scrapy занял 28 с вместо ошибки, uv — 19 с, а паук обошёл тестовые страницы, включая сжатую brotli. Дольше всего собирается zstandard: 63 с для httpx[zstd] через pip. В Dockerfile поставьте эту строку перед pip install.
Проверена только эта строка для Debian. В Windows компилятор для таких сборок входит в Microsoft C++ Build Tools; Windows мы не проверяли.
Решение 2: остаться на Python 3.14, пока не появятся колёса
Для Python 3.14 колёса brotli и zstandard есть, так что там этой проблемы нет. Чтобы узнать, появились ли колёса brotli, запустите это на Python 3.15:
python3 -m pip download --only-binary :all: --no-deps -d /tmp/wheel-check brotli16 октября команда всё ещё завершалась строкой ERROR: No matching distribution found for brotli. Как только она скачает файл .whl, колёса cp315 опубликованы и pip install scrapy работает без компилятора.
В апстриме issue #25 в google/brotli-wheels, «Python 3.15 wheels missing», открыли 9 октября, и на 16 октября ответов в нём не было. Pull request #1583 в google/brotli добавляет в CI задачу, которая собирает колёса cp315. На 16 октября он всё ещё был открыт без ревью, а единственный комментарий оставил бот CLA. В его описании сказано, что опубликовать колёса на PyPI всё равно должен мейнтейнер.
Не Scrapy? У brotlicffi есть колесо
brotlicffi 1.2.0.2 поставляется с колесом abi3, которое pip установил на 3.15. HTTPX, urllib3 и aiohttp принимают его вместо brotli, поэтому без компилятора эти варианты сработали и распаковали ответ, сжатый brotli:
pip install httpx brotlicffi
pip install urllib3 brotlicffi
pip install aiohttp aiodns brotlicffiПоследняя строка — это aiohttp[speedups] без требования Brotli. Scrapy так не умеет: на CPython ему нужен именно пакет brotli.
С zstd всё проще, чем кажется. На Python 3.14 и новее urllib3 2.8.0 и aiohttp 3.14.5 распаковывают zstd модулем стандартной библиотеки compression.zstd, поэтому оба предложили серверу zstd и распаковали ответ в zstd без дополнительных пакетов. zstandard нужен только для httpx[zstd].
Не используйте --only-binary вслепую
--only-binary :all: запрещает pip собирать что-либо из исходников. Это выглядит как очевидный обходной путь, и ошибки он не даёт:
pip install --only-binary :all: "httpx[brotli]" "aiohttp[speedups]"pip вывел INFO: This is taking longer than usual, пока перебирал версии, и установил httpx 0.18.2 (июнь 2021 года) и aiohttp 0.13.1 (декабрь 2014 года). Единственной другой подсказкой была одна строка:
WARNING: aiohttp 0.13.1 does not provide the extra 'speedups'Резолвер откатывался по старым выпускам, пока не нашёл те, чьи зависимости можно удовлетворить одними колёсами. uv pip install --no-build выбрал те же две версии и вывел warning: The package `aiohttp==0.13.1` does not have an extra named `speedups` .
Если сузить флаг до одного пакета, безопаснее не станет. pip install --only-binary brotli scrapy тоже завершается с кодом 0 и ставит Scrapy 2.17.0 — последний выпуск без требования brotli. uv сделал то же самое. Этот Scrapy обошёл тестовые страницы, но предлагал серверам только gzip, deflate, тогда как 2.19.0 с brotli предлагал gzip, deflate, br, zstd. Если ваши пауки используют async def start(), 2.17.0 их всё равно запустит.
Чтобы заметить тихий откат версии, смотрите установленные версии после каждой установки:
pip list
uv pip listЧтобы установка вместо этого громко падала, закрепите нужную версию рядом с флагом:
pip install --only-binary brotli "scrapy==2.19.0"ERROR: Could not find a version that satisfies the requirement brotli>=1.2.0; implementation_name != "pypy" (from scrapy) (from versions: none)
ERROR: No matching distribution found for brotli>=1.2.0; implementation_name != "pypy"uv с тем же закреплением остановился на error: No solution found when resolving dependencies. requirements.txt с точными версиями пакетов верхнего уровня даёт ту же защиту при каждой сборке.
Исправлено 15 октября: zope.interface без C-ускорений
Twisted, а вместе с ним и Scrapy, зависит от zope.interface. У zope.interface 8.6 колёса есть только до CPython 3.14. 14 октября без компилятора pip и uv всё равно установили его на 3.15: если C-расширение не собирается, сборка переходит на чистый Python. Ни ошибки, ни предупреждения в выводе установки не было.
Цена была видна на базовой проверке интерфейса. В лаборатории IThing.providedBy(obj) занимал 271 нс на вызов без C-расширения и 101 нс с ним. Что это значит для целого обхода, лаборатория не измеряла.
В zope.interface 8.7, вышедшем 15 октября, есть колёса cp315. 16 октября чистая установка без компилятора получила через pip и uv бинарное колесо 8.7, C-расширение импортировалось, а та же проверка заняла 102 нс. Виртуальное окружение, созданное до 15 октября, остаётся с 8.6 на чистом Python, пока вы не обновите zope.interface.
Чтобы узнать, какой вариант у вас:
python -c "import zope.interface._zope_interface_coptimizations"ModuleNotFoundError означает запасной вариант на чистом Python. С колесом 8.7 или с установленным gcc импорт прошёл.
Другие изменения 3.15, важные для скрапинга
Заметнее всего будет режим UTF-8, теперь включённый по умолчанию (PEP 686). В What's New in Python 3.15 сказано, что операции ввода-вывода без явной кодировки, например open('flying-circus.txt'), теперь используют UTF-8 независимо от окружения системы. В лаборатории с LANG=C вызов open() без encoding на 3.15 писал в UTF-8, а с -X utf8=0 возвращался к ANSI_X3.4-1968, то есть к ASCII.
Для скраперов это в основном касается экспорта. CSV- или JSON-файл, записанный через open(path, "w"), теперь в UTF-8 на любой машине, включая Windows-системы, где 3.14 брал кодовую страницу локали. Обычно это то, что нужно. Если программа дальше по цепочке ждёт старую кодировку, передайте encoding="locale" или задайте PYTHONUTF8=0; а лучше явно указывайте кодировку и при записи, и при чтении.
Если вы заодно обновляете Scrapy
Переход на Python 3.15 часто идёт вместе с новым Scrapy. Начиная с 2.16, Scrapy больше не вызывает start_requests(): паук, в котором есть только этот метод, открывается, ничего не отправляет и закрывается как завершённый, без предупреждений. В статье Scrapy обходит 0 страниц после обновления есть исправление в одну строку — async def start(), — и паук в этой лаборатории использовал именно его.
Метод и ограничения
Записано 14 октября 2026 года на хосте Ubuntu x86_64, в файловой системе официального образа python:3.15-slim (Debian 13 trixie, дайджест индекса sha256:ea4f1f29…, собран 12 октября 2026 года), запущенной в отдельном пространстве имён Linux, а не в Docker. Интерпретатор сообщил Python 3.15.0 (main, Oct 12 2026, 22:33:31) [GCC 14.2.0], с ним шли встроенный pip 26.2.1 и uv 0.13.1. В копию с компилятором gcc 14.2.0 был установлен строкой apt выше. Таблица составлена по этим запускам. 16 октября случаи Scrapy, --only-binary brotli и zope.interface повторили без компилятора: всё совпало с 14 октября, кроме zope.interface, который теперь пришёл из колеса 8.7.
Для каждого случая создавалось новое виртуальное окружение без кэша пакетов. Установленные версии и то, откуда пришёл каждый пакет — из бинарного колеса, из чисто питоновского колеса или из локальной сборки, — определялись по тегам колёс. Smoke-тесты обращались к локальному http.server, который сжимает ответ только кодировками, предложенными клиентом. Playwright был установлен, его браузеры — нет. Прокси не использовался.
Лаборатория ничего не говорит о macOS, Windows, ARM, образах на musl и сборках без GIL. PyPI меняется каждый день, поэтому повторите проверку колёс, прежде чем действовать по любой строке таблицы. Скрипт, smoke-тесты и сырые результаты лежат в папке загрузок: lab315.py, results.csv, results.json и повторный запуск 16 октября, results-2026-10-16.json.
Связанные материалы
- Прокси в Scrapy 2.19 — авторизация, ротация и ошибки прокси, которые пишет Scrapy.
- Прокси в aiohttp и прокси в curl_cffi — оба установились на 3.15 из колёс.
- Ошибка «Missing dependencies for SOCKS support» — другая ошибка установки в этом стеке.
- Сколько ГБ прокси мне нужно? — как оценить трафик, когда стек заработает. Сжатие там важно: клиент, предлагающий меньше кодировок, может скачивать больше байтов.
ipvolt строит прокси-инфраструктуру для разработчиков и агентов. Вступите в лист ожидания — одно письмо, когда откроется доступ.
Источники
- Python.org: страница выпуска Python 3.15.0
- What's New in Python 3.15: UTF-8 как кодировка по умолчанию
- PEP 686: Make UTF-8 mode default
- PyPI: файлы brotli 1.2.0
- PyPI: файлы zstandard 0.25.0
- PyPI: файлы zope.interface 8.6
- PyPI: файлы zope.interface 8.7
- PyPI: Scrapy 2.19.0
- google/brotli-wheels, issue #25: Python 3.15 wheels missing
- google/brotli, pull request #1583: Build and test CPython 3.15 wheels in CI
- Microsoft C++ Build Tools