Scroll Content Auto-Extraction User Guide
Automatically scrolls the phone screen with continuous screenshots, removes overlapping areas between adjacent screenshots, stitches them into a long image, then sends it to an AI vision model for content analysis and extraction, and finally exports to Excel (.xlsx) / Word (.docx) documents.
Table of Contents
- Feature Overview
- Three-Phase Workflow
- Core Algorithms
- Two Extraction Modes
- Agent Tool Definition
- Usage Examples
- Export Format Details
- FAQ
Feature Overview
Pain Points Addressed
| Pain Point | Solution |
|---|---|
| Per-page LLM extraction is slow and token-heavy | Stitch a long image locally first, reducing LLM calls from N pages to a few segments |
| Items truncated across screen boundaries | Overlapping stitch preserves complete items — no more discarding edge items per page |
| Status bar / TabBar repeating in the long image | Per-row grayscale signature auto-detects and removes fixed UI regions |
| Duplicate data across frames | Fingerprint Set global deduplication (overlap boundary duplicates caught by fingerprint fallback) |
| Accurate bottom-reached detection | aHash perceptual hash comparison (16×16 grayscale downsampling, similarity ≥ 97% = bottom reached) |
| Content loading delay causing incomplete screenshots | Configurable settle time after each scroll (default 800ms) |
Core Capabilities
- Fast Capture: Scrolling phase makes zero LLM calls — only screenshots + aHash bottom detection, significantly faster than per-page extraction
- Local Long-Image Stitching: Pure Canvas computation, auto-removes fixed status bars / bottom bars, precisely aligns overlapping regions between adjacent screenshots
- Auto-Segmentation for Oversized Images: Segments at 4096px with 300px overlap between segments to prevent items from being cut at boundaries
- Dual Extraction Modes: Schema structured table mode (Excel / general) and richMode image-text mode (Word-specific)
- Auto Task Completion: After successful extraction, the AI Agent task ends immediately — no further LLM decision loop
Three-Phase Workflow
flowchart TD
START([Start]) --> P1
subgraph P1[Phase 1: Auto-Scroll & Capture]
CAP0[First screen screenshot] --> SWIPE[Swipe up gesture]
SWIPE --> SETTLE[Wait settleMs]
SETTLE --> CAPN[Post-scroll screenshot]
CAPN --> HASH{aHash similarity >= 0.97?}
HASH -->|No, not at bottom| SWIPE
HASH -->|Yes, bottom reached| P1END[Capture complete]
CAPN -->|maxPages reached| P1END
end
P1END --> P2
subgraph P2[Phase 2: Overlap Removal & Stitching]
SIG[Per-row grayscale signature] --> BARS[Detect fixed top/bottom bars]
BARS --> OVERLAP[Match overlapping regions between adjacent screenshots]
OVERLAP --> STITCH[Canvas stitch into virtual long image]
STITCH --> CHUNK[Segment at 4096px
300px overlap between segments]
end
CHUNK --> P3
subgraph P3[Phase 3: AI Analysis of Image Segments]
MODE{richMode?}
MODE -->|No, Schema mode| SCHEMA[Infer field Schema from first segment]
SCHEMA --> EXTRACT[Per-segment structured JSON extraction]
MODE -->|Yes, Image-text mode| RICH[Per-segment image region + text recognition]
RICH --> CROP[Canvas crop image regions]
EXTRACT --> DEDUP[Fingerprint deduplication]
CROP --> DEDUP
end
DEDUP --> EXPORT[Export Excel / Word]
EXPORT --> FINISH[End entire Agent task]Comparison with Legacy Per-Page Extraction
| Dimension | Legacy (Per-Page) | New (Long-Image Stitching) |
|---|---|---|
| LLM Calls | 1 Schema + N pages × 1 extraction | 1 Schema + segments × 1 extraction (30 screens usually → only 3–5 segments) |
| Scroll Speed | Wait for LLM response per page | Zero LLM calls during scrolling — limited only by settleMs |
| Truncated Items | Incomplete items at top/bottom edges discarded per page | Items complete after stitching — no information loss |
| Fixed UI Interference | Every page contains status bar / TabBar | Auto-detected and removed, kept only once |
screenshots Return |
Raw per-page screenshots | Stitched long-image segments (i.e. the actual images sent to AI) |
Core Algorithms
1. Bottom Detection (aHash Perceptual Hash)
Input: Pre-scroll screenshot A, Post-scroll screenshot B
Processing:
1. Downsample A and B to 16×16 pixels each
2. Convert to grayscale (weighted: R*0.299 + G*0.587 + B*0.114)
3. Compute mean avg of 256 grayscale values
4. Each pixel >= avg → '1', otherwise → '0', producing a 256-bit hash
5. similarity = 1 - Hamming_distance / 256
Decision: similarity >= 0.97 → bottom reached, stop scrolling
2. Per-Row Grayscale Signature (Basis for Stitching)
Each screenshot width downsampled to 48 columns → per-row grayscale mean → Float32Array(height)
A single getImageData call obtains row-level features for the entire image. Subsequent fixed-bar detection and overlap matching operate on this signature array, avoiding repeated pixel reads.
3. Fixed Bar Detection (detectFixedBars)
Take row signatures from pre- and post-scroll frames:
Compare row-by-row from top — consecutive rows with |diff| < 2 → fixed top bar (status bar / nav bar)
Compare row-by-row from bottom — same logic → fixed bottom bar (TabBar / input field)
Single-side cap at 20% of screen height to prevent false positives on solid-color backgrounds
During stitching, intermediate frames have fixed bars removed; the first frame keeps the top (with status bar), the last frame keeps the bottom — ensuring the long image has complete start and end.
4. Overlap Region Matching (findOverlapOffset)
Sliding window search within the previous frame's content area [topBar, height - bottomBar):
Find the best match position matchY against the top 120 rows of the current frame's content area
Match error = average grayscale difference within the window; > 8 = match failure
Match success: current frame starts new content from row topBar + (prevEnd - matchY)
Match failure: keep the current frame's full content area (minor duplicates handled by fingerprint dedup)
With early-abandon optimization (cumulative error worse than current best → exit immediately), 30-screen stitching completes in milliseconds.
5. Long-Image Segmentation (Chunk)
Virtual long image total height = sum of all stitched segment heights
Render to Canvas at CHUNK_MAX_HEIGHT = 4096px → JPEG (quality 0.85)
CHUNK_OVERLAP = 300px overlap between segments → items won't be cut at segment boundaries
Reason for segmentation: Vision models' detail recognition degrades on extremely tall images, and Canvas has size limits.
6. Cross-Segment Deduplication (Fingerprint)
| Mode | Fingerprint Rule |
|---|---|
| Schema mode | First 2 non-empty field values trimmed and joined with | |
| richMode | First 60 characters of trimmed item text |
Tracked using a global Set<string> — items redundantly identified within the 300px overlap between segments are automatically removed.
Two Extraction Modes
Schema Mode (Default, Excel / both Format)
- Use the first segment long-image to let the LLM infer the list field schema (e.g.
{"name":"string","price":"number"}) - Extract structured JSON arrays per segment according to the Schema
- Output
result.items(table data), export to Excel / Word table
richMode Image-Text Mode (Auto-Enabled for Word Format)
- Skip Schema inference
- Have the LLM return
image_region(pixel coordinates) +text(full text) for each item per segment - Use Canvas to crop image regions from long-image segments → JPEG data URL
- Output
result.richItems, export as image-text interleaved Word document
The call entry point (react.ts / phone-tools.ts) automatically passes
richMode: truewhenoutputFormat === 'word'.
Agent Tool Definition
ExtractScrollingContent is registered as a Phone Tool, callable by ReAct / Plan-and-Resolve Agents autonomously.
Tool Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
description |
string | Yes | What data to extract, e.g. "product list with name, price, rating" |
maxPages |
number | No | Maximum number of scroll pages |
settleMs |
number | No | Wait time after each scroll (ms) |
schemaHint |
string | No | Comma-separated field name hints |
outputFormat |
excel | word | both |
No | Export format, default both; word auto-enables richMode image-text mode |
Tool Return Example
Extraction complete. Extracted 47 unique items across 12 page(s). Removed 5 duplicates. End reason: bottom_reached. Files downloaded: extract-2026-06-16-1789551234567.xlsx + .docx
Task Auto-Completion Behavior
After successful extraction (return starts with Extraction complete), the entire AI Agent task ends immediately:
- ReAct mode (react.ts): No further screenshot + LLM decision loop; current step marked as success,
task.conclusiontakes the extraction report directly,task.status = 'finished' - Plan-and-Resolve mode (agent.ts): All remaining pending steps marked as
skipped, skipping the Report phase LLM summary
When extraction yields no data (No data extracted...), the task continues normal flow — the LLM has the opportunity to adjust strategy (e.g. scroll to the correct page first, then retry).
Usage Examples
Example 1: Natural Language in Chat (Most Common)
Type directly in the AI chat box:
Extract the product list on the current page to Excel
Extract Meituan food delivery merchant list, including store name, rating, monthly sales, minimum order price
Save this Xiaohongshu note list as a Word document (with cover images)
The Agent will automatically recognize the intent and call the ExtractScrollingContent tool. The task ends automatically after extraction completes.
Example 2: Combined Commands (Navigate First, Then Extract)
Open Xiaohongshu, search for deepseek, extract the search results list to Excel, including title, author, likes
The Agent first performs app opening and searching, then calls the extraction tool and ends the task.
Example 3: Via phone-agent MCP
In an MCP-capable client (e.g. Qoder):
Use run_agent_task: Extract the news list from the current phone page to Excel, fields include title, source, time
After task completion, MCP returns a Markdown execution report (with per-step summary and tool calls).
Progress Message Reference
The onProgress callback will receive messages similar to the following in sequence:
Capturing initial screenshot...
Page 1: scrolling down (1 screenshot(s) captured)...
Page 2: scrolling down (2 screenshot(s) captured)...
Bottom detected (similarity=98.4%). Captured 9 screenshot(s).
Stitching 9 screenshot(s) into a long image...
Stitched into 3 image segment(s). Analyzing content with AI...
Inferring data schema from stitched image...
Segment 1/3: extracting data...
Segment 1/3: +15 new items (total 15)
Segment 2/3: extracting data...
Segment 2/3: +14 new items (total 29)
Segment 3/3: extracting data...
Segment 3/3: +11 new items (total 40)
Export Format Details
Excel (.xlsx) — Schema Mode
| Feature | Description |
|---|---|
| Sheet Names | Data (data) + Screenshots (screenshots, generated when screenshots are provided) |
| First Row | Column headers (field names) |
| Column Width | Auto-fit (based on maximum content length) |
| Data Types | Numbers stay as numbers, strings stay as strings, null → empty |
| Screenshot Storage | Base64 of each page screenshot stored across cells (column-limited) in the Screenshots sheet (can be decoded and reassembled into images), plus downloaded as individual image files (.png/.jpg, same prefix as Excel, numbered by page) |
Note: The community xlsx library (SheetJS) does not support embedding images in cells, so screenshots are saved in two ways: "Base64 split across cells + individual image file downloads" to ensure no image data is lost.
Word Table (.docx) — Schema Mode (both Format)
| Feature | Description |
|---|---|
| Title + Stats Row | H1 heading, "Extracted N items total, exported at [time]" |
| Table Style | Dark header, alternating row colors, auto column width |
| Screenshot Appendix | When screenshots is provided, stitched long-image segments are embedded |
Word Image-Text (.docx) — richMode (word Format)
| Feature | Description |
|---|---|
| Each Item | Cropped image (300px wide proportional scale, if available) + multi-line text paragraphs + separator line |
| Text Style | First line bold and slightly larger (title-like), remaining lines in normal style |
| Page | A4, 1.25-inch left/right margins |
FAQ
Q: Extraction result is empty?
Troubleshooting Steps:
- Confirm the phone screen is currently displaying list/card content
- Check whether
descriptionaccurately describes the data to extract - Check the console for
[ScrollExtract]logs to confirm stitching segment count and Schema inference - Try adding
schemaHintto explicitly specify field names
Q: The stitched long image has misalignment or duplicate strips?
Possible Causes:
- The page has parallax animation / sticky elements during scrolling, causing row signature match failure (the frame retains its full content area, resulting in duplicates but no data loss)
- List items have large solid-color backgrounds between them, causing overlap matching to find the wrong position
Note: Duplicate items from match failures are removed by fingerprint dedup, generally not affecting final data. If misalignment is severe, increase settleMs to allow the page to fully settle before capturing.
Q: Bottom detected too early?
Possible Causes:
- The page has a large fixed area (e.g. top banner), and the changing region after scrolling is small
endThresholdis set too high
Solution: Lower endThreshold (e.g. 0.95 or 0.93).
Q: Want faster extraction?
- Reduce
settleMs(e.g. 500ms) — suitable for static content pages - Reduce
maxPagesto limit capture range - Use a faster vision model; LLM time depends only on the number of stitched segments, not the number of scrolled pages
Q: Will segment boundaries cut items?
A 300px overlap is maintained between segments. Items cut at the boundary will appear completely in an adjacent segment. Duplicate identification is handled by fingerprint dedup.
Q: Why do Word and Excel formats have different content structures?
outputFormat: 'word' auto-enables richMode image-text mode, producing "image + free text" (richItems); excel / both use Schema mode, producing structured tables (items). The LLM prompts and outputs for the two modes are entirely different.
Q: What types of lists are supported?
| List Type | Support |
|---|---|
| Native Android RecyclerView | Supported |
| React Native FlatList | Supported |
| Flutter ListView | Supported |
| H5 list inside WebView | Supported |
| Paginated loading (non-infinite scroll) | Supported (requires配合 page-turn clicks) |
| Horizontal scrolling list | Not yet supported (currently vertical stitching only) |
Core advantage: Based on screenshots + visual AI, independent of UI dump or XPath — universal across any rendering framework.