How to Handle Pagination When Scraping
Scrapeless Agent Browser provides cloud browser sessions that can navigate paginated pages and interact with JavaScript-driven result lists.
How Should You Handle Pagination When Scraping?
Handle pagination by identifying the source's continuation mechanism, extracting records with stable identities, advancing only after the current result is accepted, and stopping on a documented or observed end state. Put an independent bound on the run so a broken continuation cannot create an unlimited crawl.
The difficult part is proving progress. A page label can change while the records remain the same. An infinite-scroll list can replace old nodes instead of growing. A successful response can contain an access message. A correct collector tests the content and state that matter rather than equating a click or request with a new accepted page.
TL;DR
- Follow observed continuation behavior. Discover next links or request state before constructing page URLs.
- Use record identity to measure progress. Element counts and scroll height are supporting signals.
- Distinguish source end from run limits. A page cap produces a bounded collection, not proof of completeness.
- Keep source permissions and workload bounds explicit. Browser access does not expand collection authorization.
Which Pagination Pattern Does the Source Use?
The source's actual state transition determines the pagination pattern. Inspect an approved page and observe what happens when a user advances. A next link can navigate to a new document. Numbered controls can alter a query parameter. A load-more button can append records. A scroll sentinel can trigger another request without a visible button.
Inspect structured responses when access is permitted and their meaning is understood. The browser interface may display page numbers while the underlying request uses an opaque cursor. Use the supported interface and permission boundary; a discoverable endpoint is not automatically a public collection API.
| Pattern | Advance action | Progress evidence | Possible end evidence |
|---|---|---|---|
| Next link | Follow the current next target | Expected new records or continuation state | Confirmed absence of a valid next target |
| Numbered pages | Use observed supported page navigation | Changed window with stable record keys | Source-defined final page |
| Load more | Activate the enabled control | New accepted identities | Explicit exhaustion state |
| Infinite scroll | Move the relevant container or sentinel | New identities or request continuation | Confirmed source end signal |
How Do You Follow Next Links Safely?
A next-link collector reads the current page's continuation target, resolves relative references against the page URL, and validates the destination before following it. The HTML link relationship model includes a next relationship, but sites can also express pagination through their own markup.
Prefer semantic attributes and stable page structure over generated class names when those signals identify the intended control. Confirm that the target advances the same collection rather than opening a related category or advertisement. Keep the chosen filter and ordering context intact.
Track visited page states to detect loops. A repeated URL can identify a next-link cycle, but some applications use one URL for many states. In those cases, record the relevant cursor, source page state, or a fingerprint of accepted record keys. A URL-only guard would incorrectly stop a valid stateful list.
Validate the destination origin before sending credentials. A scraped link is untrusted input. A collector should not forward an authorization header or session material to an unrelated host simply because the page calls that link “next.”
When Can You Use Numbered Page URLs?
Use numbered page URLs when the source exposes and supports the observed URL pattern. Confirm the first transition and any final-page signal before building a range. Do not assume every collection uses a page query parameter or that visible page numbers correspond to simple arithmetic offsets.
Changing collections complicate a numbered walk. Insertions and deletions can shift result windows, producing overlaps or gaps. Stable identities remove duplicate output, but they cannot recover records skipped between windows. Keep the source's sort order fixed when the interface permits it and report the collection's observation scope.
The need for a unique ordering in limited queries illustrates the underlying issue. A visible sort by popularity can change while collection proceeds. Even a chronological sort needs a tie-breaking policy if records share the same time.
How Do Load-More and Infinite-Scroll Lists Differ?
Load-more lists expose an explicit action, while infinite-scroll lists trigger loading when a relevant viewport condition is met. Both require waiting for source-specific progress after the action. A click completing or a scroll event firing does not establish that additional records arrived.
The Intersection Observer mechanism explains how visibility changes can trigger asynchronous work. Some sites observe a sentinel inside a nested scroll container rather than the document viewport. Scrolling the document may leave that sentinel untouched.
Virtualized lists can reuse DOM elements as the visible window moves. The element count or page height may remain stable even when new records become visible. Collect stable keys as each window is observed, and use an end signal or continuation state that fits that implementation.
A disabled button is also ambiguous during loading. Distinguish a temporary loading state from a source-defined exhausted state. If progress cannot be established within the run's allowed observation window, stop with an unresolved outcome instead of claiming the source has ended.
What Does a Bounded Next-Link Example Look Like?
A bounded example can demonstrate traversal without claiming complete collection. The following Python program uses the public Books to Scrape demonstration catalog, follows its observed next link, validates the expected host, and accepts at most two pages. It uses the Python standard library and does not call Scrapeless.
The code was executed for this article's example. It discovers book detail links from title-bearing anchors in this specific demonstration markup; that selector rule is not a universal catalog parser. The output below is the captured result, and the page-cap status deliberately identifies a partial traversal.
from html.parser import HTMLParser
from urllib.parse import urljoin, urlparse
from urllib.request import Request, urlopen
class CatalogPage(HTMLParser):
def __init__(self):
super().__init__()
self.in_next = False
self.next_url = None
self.records = []
def handle_starttag(self, tag, attrs):
attrs = dict(attrs)
if tag == 'li' and 'next' in attrs.get('class', '').split():
self.in_next = True
if tag == 'a' and self.in_next:
self.next_url = attrs.get('href')
if tag == 'a' and 'title' in attrs:
self.records.append((attrs.get('href'), attrs['title']))
def handle_endtag(self, tag):
if tag == 'li':
self.in_next = False
url = 'https://books.toscrape.com/catalogue/page-1.html'
seen_pages, seen_items = set(), set()
reason = 'page cap'
for _ in range(2):
if urlparse(url).hostname != 'books.toscrape.com':
raise ValueError('Unexpected continuation host')
if url in seen_pages:
raise ValueError('Repeated page URL')
seen_pages.add(url)
with urlopen(Request(url, headers={'User-Agent': 'Mozilla/5.0'}),
timeout=20) as response:
if response.geturl() != url:
raise ValueError('Unexpected redirect')
document = response.read().decode('utf-8')
parser = CatalogPage()
parser.feed(document)
if not parser.records:
raise ValueError('Expected book records are absent')
for href, title in parser.records:
seen_items.add(urljoin(url, href))
print('Accepted page:', url, 'records:', len(parser.records))
if not parser.next_url:
reason = 'source end'
break
url = urljoin(url, parser.next_url)
print('Unique books:', len(seen_items), '| Stop:', reason)
Captured output:
Accepted page: https://books.toscrape.com/catalogue/page-1.html records: 20
Accepted page: https://books.toscrape.com/catalogue/page-2.html records: 20
Unique books: 40 | Stop: page cap
The program accepts the current page before advancing, detects repeated page URLs, and stores unique item URLs. A production workflow should replace the in-memory set with a destination whose keys and progress boundary match its output contract. It should also distinguish source emptiness from an extraction failure using source-specific evidence.
Where Is a Browser Necessary?
A browser is useful when pagination requires JavaScript execution, interactive controls, or authorized session state. Scrapeless Agent Browser provides that controlled browser surface. The Agent Browser connection configuration describes its setup; the collector still defines selectors, progress checks, and storage.
The Scrapeless pagination walkthrough covers common page-control shapes. Use those shapes as discovery categories, then verify the current target. A scroll-height heuristic can be useful evidence on an ordinary growing document, but it should not be treated as a universal end condition.
A browser does not remove access restrictions or make a collection complete. When a page shows an access challenge or permission error, stop accepting its content as records and record the access outcome. Keep authorized session state consistent across the page chain where the source requires it.
How Should You Record Completion and Operate Responsibly?
Record why the run ended, the collection context, and the accepted record boundary. Source exhaustion, page cap, record cap, elapsed-time cap, and unresolved progress are different states. Persist accepted output before advancing its durable checkpoint so an interruption does not silently skip a window.
Review source terms and applicable collection rules before running a crawl. The Robots Exclusion Protocol describes crawler directives and explicitly distinguishes them from access authorization. Respecting robots rules is part of source handling; it does not alone settle permission to collect or reuse the data.
Keep per-source workload modest and bounded by the source policy. Parallelism is appropriate only when windows are independent and the workload is permitted. Cursor chains usually require sequential discovery. Do not distribute one restricted workload across identities to defeat its intended allowance.
Use Scrapeless pricing to plan browser collection costs, then monitor accepted unique records and unresolved partitions. A larger page count is not evidence of a better dataset if the added pages repeat records or contain unrelated content.
Conclusion
Choose the pagination branch from observed source behavior, verify progress with stable identities, and preserve an explicit end reason. A collector should be able to explain which pages or states it accepted and why it considers the resulting scope complete or partial.
Put the Collection Layer Into Practice
Choose the Scrapeless collection capability that matches your source, then apply the validation and operating decisions described above.
Sign up today and get $5 in free credit — no credit card required.
Claim Your $5 Credit →FAQ
Is collecting public paginated data always permitted?
No. Public visibility alone does not settle permission, terms, privacy obligations, or reuse rights. Define the permitted source and purpose before collecting.
Do pagination workflows always need a proxy?
No. The need depends on the source and approved deployment. A proxy does not expand access permission or remove the requirement to respect the source's workload policy.
What if an access page appears instead of records?
Mark the affected state as an access outcome and stop accepting it as dataset content. Confirm the authorized session and source policy before continuing collection work.
What if the site's markup changes?
Reinspect the current record and continuation structure, then update source-specific selectors and acceptance checks. A selector returning no items does not prove the source is empty.
Can pagination run without an AI agent?
Yes. The bounded Python example runs directly without an AI agent. Browser-dependent workflows can also use ordinary automation code with explicit state and progress checks.
Can page chains run concurrently?
Only independently addressable windows should be considered for parallel collection, within the permitted source workload. A next-token chain normally depends on the previous response.