Skip to content

fix(pagination): advance from a bare page-1 URL with numbered links (1.6.4) - #191

Merged
vedaant00 merged 1 commit into
mldsveda:mainfrom
vedaant00:vs-001
Sep 25, 2026
Merged

vedaant00 merged 1 commit into
mldsveda:mainfrom
vedaant00:vs-001

Conversation

@vedaant00

Copy link
Copy Markdown
Collaborator

Fixes #187.

Problem

On the common layout where page 1 is the bare URL (/products) and only pages 2+ carry a ?page= token, _extract_page_number returns None, and the current_num is not None guard discarded the numbered links entirely — even though they already contained the answer.

scrape_url(url, max_pages=N) therefore scraped one page and reported success. It was masked only when the site also emitted <link rel="next"> or a "Next" anchor, so it bit exactly the sites that paginate with bare numbers.

soup = BeautifulSoup('<a href="?page=2">2</a><a href="?page=3">3</a>', "html.parser")
find_next_page_url(soup, "https://x.com/list")        # None   <- crawl stops
find_next_page_url(soup, "https://x.com/list?page=2") # ?page=3

Fix

When there is no current page number, follow the lowest forward link rather than stepping from an assumed 0/1.

That distinction matters for offset-style sites. A bare URL has no offset in it, so _is_offset_style is False and _page_step would return 1 — wrong for a site that steps by 20. The links themselves carry the real values, so taking min(num > 1) handles both shapes with one rule:

current URL links result
/list (bare) ?page=2, ?page=3 ?page=2
/list (bare) ?start=20, ?start=40 ?start=20
/list?page=2 ?page=2, ?page=3 ?page=3 (unchanged)
/list?start=20 ?start=0/20/40 ?start=40 (unchanged)
/list (bare) ?page=1 only None (no loop)

Existing behavior is untouched whenever the current URL has a page number.

Tests

Four regression tests covering the issue's acceptance criteria: bare page-1, offset-style bare page-1, unordered links, and the no-forward-link case. Three of the four fail on pre-fix code (the fourth asserts None, which was already the old behavior), verified by reverting pagination.py and re-running. The 26 existing pagination tests stay green.

604 passed, ruff check + format clean. Bumped to 1.6.4.

Also

server.json advertised 22 MCP tools; the actual count is 24 (verified against the @mcp.tool decorators). Corrected in the same bump since it ships with the release metadata.

🤖 Generated with Claude Code

…1.6.4)

Fixes mldsveda#187. On the common layout where page 1 is the plain URL (/products)
and only pages 2+ carry a ?page= token, _extract_page_number returned None,
and the `current_num is not None` guard discarded the numbered links entirely
even though they already said where to go next. scrape_url(url, max_pages=N)
then silently scraped one page and reported success. It was masked only when
the site also emitted <link rel="next"> or a "Next" anchor, so it bit exactly
the sites that paginate with bare numbers.

Follow the lowest forward link (page 2) instead of stepping from an assumed
0/1. That matters for offset-style sites too: a bare URL has no offset in it,
so _page_step can't infer the page size and would wrongly return 1, whereas
the links themselves carry the real values (0/20/40 -> ?start=20).

Pages whose only numbered link is <= 1 still return None rather than looping.

Also corrects server.json's stale MCP tool count (22 -> 24, verified against
the @mcp.tool decorators).

604 passed, ruff clean. Bump to 1.6.4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vedaant00
vedaant00 merged commit 4e99e92 into mldsveda:main Sep 25, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Numbered pagination never advances from a page-1 URL that has no page parameter

1 participant