Обработка пагинации и бесконечной прокрутки в скрейперах
TL;DR
Пагинация может быть ссылкой на следующую страницу, номерным URL, API курсора, управлением "Загрузить больше" или запросом, запускаемым при прокрутке; проверьте фактический источник данных перед написанием цикла.
Остановитесь на стабильном терминальном сигнале: нет следующей ссылки или курсора, неизмененный набор элементов, лимит страниц или явное окончание источника. Не используйте while True без границ.
Удалите дубликаты по стабильному идентификатору элемента или каноническому URL; многократные страницы и перестановка результатов - это нормально в меняющихся каталогах.
Playwright может прокручивать или щелкать, когда разрешенный сайт действительно требует взаимодействия с браузером. Задокументированный API источника обычно легче для контрольных точек.
Nstdata Crawl обнаруживает связанные страницы в рамках maxDepth, maxPages, правил включения и исключения, но обход сайта не гарантирует наличие каждого элемента только с прокруткой.
Почему пагинация ломает иначе работающие скрапер?
Пагинация ломает скрапер, когда скрипт рассматривает первый ответ как всю коллекцию или предполагает, как загружаются дополнительные результаты. Сайт может разместить <a rel="next"> в HTML, создать номерные URL, возвратить курсор из конечной точки JSON или добавить карточки после прокрутки. Это разные контракты. Проверьте панель сети браузера и задокументируйте разрешенный способ доступа к источнику перед внедрением одного из них.
Для многопстраничной коллекции Nstdata Crawl может обнаружить и рекурсивно получить разрешенные URL, в то время как специфическое для источника правило продолжения все еще требует проверки.
Порядок результатов может измениться во время выполнения обхода. Новые элементы могут переместить старые на следующую страницу, что приводит к дубликатам или пропускам. Используйте стабильный ключ элемента и окно обхода или снимок источника, когда API поддерживает это. Номер страницы является инструкцией навигации, а не идентификатором для содержащихся в ней элементов.
Попробуйте Nstproxy Crawl - Начните Бесплатно Уже Сегодня
Что вам нужно перед началом?
Подготовьте одобренный источник, известную первую страницу, контейнер элемента и стабильный идентификатор элемента, механизмы следующей страницы, а также явный бюджет по максимальному количеству страниц или элементов. Для примеров на Python, основанных на ссылках, установите requests и Beautiful Soup. Для рабочего процесса только в браузере установите Playwright и его бинарный файл браузера. Держите учетные данные вне исходного кода и уважайте задокументированные условия и лимиты скорости сайта.
Запишите page_url, fetched_at, next_url или cursor, идентификаторы элементов и отпечаток набора элементов для каждого шага. Эта книга учета делает очевидным зависшую или повторяющуюся страницу и поддерживает возобновление после сбоя. Курсор, предоставленный источником, должен сохраняться точно так же, как он был возвращен; не выдумывайте новый курсор, увеличивая номер страницы.
Как следовать за ссылкой на следующую страницу?
Используйте этот метод, когда возвращаемый HTML включает ссылку на следующую страницу. Код является шаблоном для одобренного источника; селекторы должны быть подтверждены на живой странице.
Метод 1: Следуйте за HTML пагинацией
Шаг 1. Определите ссылку, которая указывает на следующую страницу, и стабильный селектор элемента. Предпочитайте rel="next", когда сайт предоставляет его, но убедитесь, что он указывает на предполагаемый список.
Шаг 2. Получайте одну страницу за раз, разрешайте относительные URL и останавливайтесь на отсутствующем или повторяющемся следующем URL:
from urllib.parse import urljoin
import requests
from bs4 import BeautifulSoup
defpages(start_url, max_pages=10): seen_urls =set() url = start_url
with requests.Session()as session:for _ inrange(max_pages):if url in seen_urls:raise RuntimeError(f"Pagination loop at {url}") seen_urls.add(url) response = session.get(url, timeout=(5,20)) response.raise_for_status() soup = BeautifulSoup(response.text,"html.parser")yield response.url, soup
link = soup.select_one('a[rel="next"][href]')if link isNone:return url = urljoin(response.url, link["href"])
Шаг 3. Извлеките и удалите дубликаты идентификаторов элементов из каждой возвращаемой страницы. Сохраните последнюю завершенную страницу и обнаруженный следующий URL перед продолжением. Не предполагайте, что страница с меньшим количеством карточек обязательно является последней; используйте фактический терминальный сигнал сайта.
Как вы обрабатываете курсор или номерованный API?
Используйте задокументированный API источника, когда он доступен и одобрен. Курсор - это непрозрачный токен продолжения; передайте его обратно точно так же, как получили. Проверьте, возвращает ли API явный next_cursor, has_more или next URL. Убедитесь, что нулевой или отсутствующий токен действительно означает завершение в этом API. Для номерованных страниц используйте наблюдаемый параметр сайта и ограничьте номер страницы.
Метод 2: Контрольная точка курсорной пагинации
Шаг 1. Сохраните конечную точку, разрешенные параметры и пример схемы ответа из документации источника или панели сети.
Шаг 2. Получите одну страницу, подтвердите ее массив элементов, записывайте принятые записи идемпотентно, а затем сохраните возвращенный курсор. Запись должна завершиться до того, как курсор будет продвинут; в противном случае сбой может пропустить страницу.
Шаг 3. Остановитесь, когда API сообщает о отсутствии продолжения или когда возвращаемые курсор и идентификаторы элементов совпадают. Ограничьте частоту запросов и воспринимайте 429 как сигнал для паузы. Курсор может истечь или зависеть от сеанса; ваш план восстановления должен указывать, нужно ли начинать с известного снимка.
Этот метод обычно легче отслеживать, чем прокрутка в браузере, потому что состояние продолжения явно. Документация по паукам Scrapy показывает, как парсеры могут выдавать последующие запросы и элементы в виде отдельных результатов.
Как вы скребите бесконечную прокрутку или загружаете больше?
Используйте взаимодействие с браузером только тогда, когда контент действительно загружен на страницу, и источник разрешает такой рабочий процесс. Руководство по действиям Playwright рекомендует прокручивать известный элемент в поле зрения, когда это действие вызывает дополнительный контент. Избегайте слепых циклов scrollTo(0, document.body.scrollHeight): сайт может добавлять объявления, использовать прокручиваемый контейнер или никогда не показывать конечную высоту.
Метод 3: Продвиньте список браузера с помощью ограниченного цикла
Шаг 1. Подтвердите контейнер списка, атрибут идентификатора элемента и наличие либо кнопки "Загрузить больше", либо сигнала внизу списка. Используйте локализуемый элемент, а не произвольную задержку, в качестве условия готовности. [Скриншот: Контейнер списка и управление загрузкой больше или нижний сигнал на отображаемой странице.]
Шаг 2. На каждой итерации собирайте видимые идентификаторы элементов, выполняйте одно нажатие или прокрутку, затем ждите нового идентификатора или задокументированного конечного состояния. Установите максимальное количество итераций и тайм-аут. Если набор идентификаторов не увеличивается, остановитесь и диагностируйте страницу, а не нажимайте бесконечно.
Шаг 3. Сохраните вновь принятые элементы и наблюдаемое состояние списка. Некоторые виртуализированные списки удаляют старые узлы DOM во время прокрутки; поддерживайте свой собственный набор seen_ids, вместо того чтобы рассматривать текущее количество DOM как полное покрытие.
Документация по локаторам Playwright поддерживает локаторы, основанные на роли и тексте, а также встроенное ожидание. Для разрешенного источника стабильная роль кнопки и доступное имя, как правило, легче поддерживать, чем созданный CSS-класс. Если сайт предлагает одни и те же элементы через официальный фид, предпочтите этот источник и сохраняйте путь браузера только для проверки.
Как Nstdata может помочь собирать многостраничные сайты?
Nstdata Crawl — это API веб-кулирования для данных, готовых к LLM, который может превратить проверенный корень сайта в ограниченный набор записей страниц. Он рекурсивно находит ссылки, обрабатывает рендеринг JavaScript и возвращает форматы, подходящие для последующего парсинга или переваривания ИИ. Он подходит для связанных разделов документации, страниц категорий и инвентаризации контента. Для списка, который существует только за пределами пользовательского состояния прокрутки, протестируйте одну представительную страницу и проверьте вывод, прежде чем предполагать полное покрытие.
Выходы, готовые к LLM: Markdown предоставляет RAG и рабочие процессы агентов более чистый текст с заголовками и ссылками; HTML и сырые данные сохраняют структуру для извлечения объектов; ссылки раскрывают обнаруженную навигацию; скриншоты и PDF помогают подтвердить текущее состояние. Эти шесть категорий перечислены в документации API Crawl.
Встроенные прокси: Обычная работа Crawl наследует управляемую маршрутизацию Nstdata. Вы предоставляете x-api-key и параметры работы, без отдельных полей для прокси Host, Port, Username, Password или Protocol. Это упрощает повторное получение, но не позволяет превышать разрешенную скорость источника.
Контроль области:maxDepth, maxPages, includeUrls и excludeUrls удерживают связанную обнаружение в пределах. Ваше приложение по-прежнему сопоставляет обнаруженные URL с ожидаемым инвентарем и проверяет наличие отсутствующих элементов только прокрутки.
Как вы добавляете Nstdata Crawl в рабочий процесс с пагинацией?
Шаг 1. В Панель управления → Песочница для обхода, протестируйте первую утвержденную страницу списка и получите API-ключ. Решите, раскрывает ли список связанные страницы с деталями; если нет, проверьте поведение прокрутки отдельно.
Шаг 2. Отправьте ограниченную задачу для сайта. Замените образцовый домен и шаблоны на утвержденный диапазон источников:
curl--request POST 'https://api.nstdata.io/api/v1/crawl'\--header"x-api-key: ${NSTDATA_API_TOKEN}"\--header'Content-Type: application/json'\--data'{"url":"https://example.com/docs/","formats":["markdown","links"],"maxDepth":2,"maxPages":50,"includeUrls":["*example.com/docs/*"],"excludeUrls":["*example.com/account/*"]}'
Шаг 3. Сохраните возвращаемый идентификатор обхода, опросите GET /api/v1/crawl/status/{crawlId}, затем по странице через GET /api/v1/crawl/pages/{crawlId}, используя возвращенный курсор. Сравните обнаруженные URL и принятые идентификаторы элементов с ожидаемым списком источника. Документированное API требует активного ключа; это пример конфигурации, а не заявленный активный обход.
Для списков с высокой частотой изменений важны как идентификаторы элементов контрольных точек, так и политика повторного посещения, как и механизм пагинации. Гид по обнаружению страниц на сайте охватывает способы наполнения инвентаря URL, в то время как гид по автоматизированному сбору данных обсуждает повторяющиеся задания. Облачный браузер Nstdata — это соответствующий отдельный продукт, когда одобренный рабочий процесс требует продолжительного взаимодействия со страницами.
Как вы подтверждаете, что многопагенный обход завершен?
Сравните количество принятых элементов и стабильные идентификаторы с общим числом, отображаемым источником, или документированным количеством API, когда это возможно. Соответствующее количество само по себе недостаточно, если дублирующиеся идентификаторы заменили отсутствующие. Просмотрите первые, средние и последние страницы; подтвердите конечную следующую ссылку или курсор; и выберите элементы, добавленные во время запуска обхода. Для изменяющихся списков запишите окно обхода и примите во внимание, что снимок может потребовать второго прохода для сверки. Отчет о покрытии должен представлять собой измеренный набор, а не необоснованное утверждение «все страницы».
Для ограниченного проектирования обхода гид по безголовым браузерам добавляет готовность и аспекты контрольных точек.
В: Гарантирует ли прокрутка вниз, что каждый элемент был собран?
Нет. Виртуализированные списки, задержанные запросы, ошибки и лимиты серверной стороны могут оставить пробелы. Убедитесь в стабильных идентификаторах элементов и конечном сигнале.
В: Должен ли я использовать номера страниц или курсоры?
Используйте метод продолжения, наблюдаемый или документированный источником. Не преобразуйте непрозрачный курсор в предполагаемый номер страницы.
В: Выполняет ли Nstdata Crawl автоматически каждое взаимодействие «Загрузить больше» на сайте?
Не подразумевайте это. Проверьте конкретное состояние страницы и сверяйте результаты с ожидаемым инвентарем; используйте рабочий процесс взаимодействия, когда это необходимо.
В: Как мне возобновить после сбоя?
Сохраните принятые идентификаторы элементов и последнюю зафиксированную следующую ссылку или курсор. Продолжайте состояние только после надежной записи.
Lena Zhou
Oct. 30th 2026
Сканируйте целые сайты одним API-запросом
Успешность 99,8% с рендерингом JavaScript
Получайте чистые данные для LLM в разных форматах
Преобразуйте любой сайт в Markdown, HTML, JSON, ссылки, PDF и другие форматы без управления инфраструктурой сканирования.