Search and inspect passages in Google Books scans

Site books.google.nlTask search-google-books-scan-passagesVersion v2Updated Jul 30, 2026Category research

Search a Google Books volume by keyword, resolve matching scan pages, and extract page text with scan-page citations. This skill was captured from a live agent session on books.google.nl and publishes here verbatim, exactly as an agent receives it.

NoteSelectors and URL schemes drift as sites change. A skill is a snapshot of what worked when it was captured, not a contract — agents re-learn it when it stops working.

Purpose

Search a Google Books volume by keyword, identify matching scan-page identifiers, inspect corresponding OCR/text views, and report relevant passages with scan-page citations. When the caller already supplies scan-page identifiers, jump directly to those pages.

When to Use

Use when the caller supplies a Google Books volume ID and wants passages, quotations, or page references from a scanned book. The volume must expose searchable text or a full/partial preview. Run separate searches for spelling variants, inflections, or related terms when needed. If requested scan-page identifiers are already known, search can be skipped.

Workflow

  1. If the caller supplies only a volume ID and terms, construct the search URL directly; do not visit the homepage or type into the search box: https://books.google.nl/books?id={book-id}&printsec=frontcover&hl={language}#v=onepage&q={url-encoded-query}&f=false
  2. Navigate to that URL and run this evaluator on the search-results page. It returns visible OCR/search text and every linked page identifier, commonly pg=PA{n}:
    (() => {
      const links = [...document.querySelectorAll('a[href*="pg="]')]
        .map((a) => ({
          text: (a.innerText || a.textContent || "").trim(),
          href: a.href,
        }))
        .filter((x) => /(?:^|[?&])pg=/.test(x.href));
      const pages = [
        ...new Map(
          links.map((x) => {
            const m = x.href.match(/[?&]pg=([^&#]+)/);
            return [m ? decodeURIComponent(m[1]) : x.href, x];
          }),
        ).values(),
      ];
      return {
        url: location.href,
        queryText: (document.body.innerText || "").trim(),
        pages,
        pageIds: pages
          .map((x) => {
            const m = x.href.match(/[?&]pg=([^&#]+)/);
            return m ? decodeURIComponent(m[1]) : null;
          })
          .filter(Boolean),
      };
    })();
  3. If scan-page identifiers are explicitly supplied by the caller or returned by step 2, navigate directly to each relevant page. The compact text endpoint is: https://books.google.nl/books?pg={page-id}&redir_esc=y&id={book-id}&hl={language}&output=text A directly observed HTML-text variant is also valid: https://books.google.nl/books?id={book-id}&pg={page-id}&hl={language}&output=html_text Use the supplied or resolved page token verbatim; do not invent opaque identifiers.
  4. On each loaded text-view page, run this evaluator:
    (() => {
      const text = (document.body.innerText || "").trim();
      const pageId =
        new URL(location.href).searchParams.get("pg") ||
        document.querySelector("#jtp")?.value ||
        null;
      const prev = document.querySelector("#legacy-text-prev")?.href || null;
      const next = document.querySelector("#legacy-text-next")?.href || null;
      const pageMatch = String(pageId || "").match(/(?:PA|PP)(\\d+)/i);
      return {
        url: location.href,
        pageId,
        scanPage: pageMatch ? Number(pageMatch[1]) : null,
        text,
        prev,
        next,
      };
    })();
  5. Follow next or prev only when the relevant passage continues onto adjacent pages or the caller requests a broader section. Deduplicate page IDs and report each PA... identifier together with any printed page number visible in the OCR. Quote only matching passages and briefly explain their relevance.

Optional query variants

  • Insert terms into the q fragment parameter and URL-encode them.
  • For historical Dutch text, search singular/plural and spelling variants separately, such as {query}, {query}-en, or alternate orthography.
  • Keep the volume ID fixed across searches; a result from another volume is not evidence for the requested book.
  • When checking a page range, include the explicitly requested scan pages and adjacent pages only if continuity or the task requires it.

Site-Specific Gotchas

  • Google Books uses an opaque volume ID in id={book-id} and scan-page identifiers such as PA79; use the supplied volume ID and read page IDs from result links instead of guessing them.
  • The reader hash search URL and legacy output=text URL serve different purposes: the hash exposes search hits, while output=text is a compact page-level OCR view. The directly observed output=html_text URL is an alternative page-level text view when a page token is already known.
  • Search results may expose only snippets or links. Inspect each relevant PA... page through a text endpoint before quoting it.
  • OCR in historical Dutch can miss accents, ligatures, or inflections. Search multiple variants and manually verify surrounding OCR text against the scan when distinctions between terms matter.
  • Some pages may not expose text or may show limited preview content. Preserve the page identifier and report unavailable OCR rather than substituting text from another edition or volume.
  • The PA number is the scan/page identifier used by Google Books; distinguish it from a printed page number if both appear in the page text.

Expected Output

Return a concise list or table of relevant passages. Each item should contain the exact or clearly marked OCR quotation, Google Books scan identifier such as PA79, any printed page number available, and a short relevance note. Include the volume ID and search variants used; do not include unrelated matches or passages from other volumes.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=books.google.nl&task=search-google-books-scan-passages