flutter_ai_scrapper 2.0.0
flutter_ai_scrapper: ^2.0.0 copied to clipboard
On-device AI web scraping for Flutter. Parses real HTML with a DOM, harvests JSON-LD and OpenGraph for free, and falls back to a local Gemma model or any OpenAI/Claude-compatible provider for schema-t [...]
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
2.0.0 - 2026-09-02 #
The official 2.0 release of flutter_ai_scrapper β an architectural rebuild delivering an HTML5 DOM parser, zero-cost deterministic metadata harvesting, on-device Gemma & cloud AI extraction, pure-CSS site recipes, and zero-dependency Material 3 widgets.
β οΈ Breaking Changes & Migration #
- HTML5 DOM Engine: Replaced legacy regular expression matching with an HTML5 spec-compliant DOM parser. Element extraction correctly pairs nested tags and respects true DOM hierarchies.
- Class Filtering:
.select('.class')evaluates exact class name tokens instead of substring containment. - Entity Decoding: All text nodes automatically decode HTML5 entities (e.g.
&becomes&). - Platform Minimums:
- Android:
minSdkVersion 24(Android 7.0),compileSdkVersion 36. - iOS:
iOS 15.0+.
- Android:
- API Modernization:
MobileScraperis@Deprecatedin favor ofAiScrapper.open()andScrapedPage.- See
doc/MIGRATION.mdfor full migration instructions.
π Key Features Added in 2.0 #
- Tier 1 (Deterministic Foundation): Zero AI tokens, <2ms execution. Full DOM querying, Readability article prose extraction, and automatic JSON-LD / Microdata / OpenGraph structured harvesting.
- Tier 2 (Typed Schema Extraction): Schema-as-tool extraction with on-device Gemma models (
flutter_gemma) or cloud fallback (OpenAiProvider,AnthropicProvider,CustomProvider). - Tier 3 (Natural Language Asking):
page.ask('query')infers typed schemas and executes automated extractions. - Tier 4 (Pure-CSS Selector Recipes):
RecipeRunnerruns synthesized CSS selectors with 0 AI tokens, sub-millisecond latency, and automatic layout drift detection. - Output & Codecs: Deterministic normalizers (dates, money, phone, URL, numbers) and RFC 4180 CSV, Markdown table, and typed object codecs.
- Privacy & Security:
allowCloudEgress: falseprivacy gate by default, plusKeySanitizerAPI key redaction. - Material 3 UI Suite:
ModelManagerSheet,ProviderSettingsSheet,ResultViewer,StreamingTextView, andExtractionConsole.
2.0.0-rc.1 - 2026-09-02 #
Phase 6: Output codecs, deterministic normalizers, and zero-dependency Material 3 UI widgets.
Added #
- Deterministic Value Normalizers:
DateNormalizer: Parses ISO-8601, RFC-2822, human-readable dates, and relative times ("yesterday", "N hours ago") to standard UTC ISO-8601 strings.MoneyNormalizer: Multi-currency symbol detection ($,β¬,Β£,Β₯,βΉ) and ISO codes with European/US separator handling; completely closes the fabricated-$issue.PhoneNormalizer: E.164 standardization with domestic region hints.UrlNormalizer: Resolves relative URLs and strips marketing/tracking query parameters (utm_*,fbclid,gclid).NumberNormalizer: Locale-aware thousands/decimal separators and shorthand suffixes (k,M,B,%).
- Output Codecs (
codecs.dart):toJsonString: Serializes extraction results with optional provenance audit blocks.toCsv: Exports to RFC 4180 CSV with nested map flattening and cell escaping.toMarkdownTable: Clean GitHub Flavored Markdown table generation.toTyped<T>: Deserializes results into strongly-typed domain model instances.toPrettyString: Colorized/indented console debugging string.
- Material 3 UI Widgets (Zero External State Management):
ModelManagerSheet: Manages on-device Hugging Face models, download progress, Wi-Fi toggle, storage statistics, and deletion.ProviderSettingsSheet: Fallback chain configuration, per-provider settings, test connection, token spend, andallowCloudEgressprivacy switch.ResultViewer: Interactive tabbed view (Table, JSON, Markdown, Raw) with field-level Provenance Badges.StreamingTextView: Real-time token streaming with collapsible thinking/reasoning blocks.ExtractionConsole: End-to-end interactive scraping console with pipeline stage indicators.
- Demo App (
example/lib/main.dart):- Rebuilt with full Material 3 dynamic themes in light and dark mode, demonstrating all four API tiers (Quick Scrape, Typed Schema, Ask Page, Recipes).
2.0.0-dev.6 - 2026-09-02 #
Phase 5: Selector recipes, DOM structural skeleton, and natural-language planner.
Added #
- DOM Structural Skeleton (
StructuralSkeleton):- Condenses arbitrary HTML trees down into a token-efficient DOM skeleton.
- Elides textual content and collapses consecutive repeated siblings with
count="N"and comment annotations (<!-- repeated N times -->). - Automatically bounds depth and budget under 1,500 tokens for massive 400 KB+ catalogue pages.
- Pure-CSS Recipe Runner (
RecipeRunner):- Executes site extraction recipes using pure CSS selectors and regex parsing with zero AI inference tokens.
- Sub-millisecond execution for both single-entity objects and collections.
- Automatically flags structural drift if container selectors or key fields match 0 elements.
- Recipe Model & Store (
Recipe,FieldSelector,RecipeStore):- Schema-stable recipe hashes (
Recipe.hashSchema(schema)). - Time-to-live expiration and eviction.
RepairPolicysupport (resynthesize,fallbackToAi,fail).
- Schema-stable recipe hashes (
- Self-Verifying Recipe Synthesizer (
RecipeSynthesizer):- Synthesizes candidate selector recipes from a DOM skeleton using language models.
- Runs candidate recipes against the source page and self-verifies data yield before storage, rejecting faulty selectors immediately.
- Natural-Language Planner (
Planner):- Translates free-form natural language queries into typed schemas (
Schema.objectandSchema.list). - Infers field types (
money,number,date,url,string) and query cardinality (listvsobject). - Emits
PlannedExtractionexposing the inferred schema to callers for inspection.
- Translates free-form natural language queries into typed schemas (
- Public
page.ask()API:- One-line natural-language scraping with automatic selector recipe caching: expensive AI judgment on page 1, deterministic zero-token CSS execution on pages 2βN.
2.0.0-dev.5 - 2026-09-02 #
Phase 4: Cloud providers and fallback engine.
Added #
- OpenAI-compatible adapter (
OpenAiProvider):- Targets
POST {baseUrl}/chat/completionswith first-classbaseUrlparameter covering OpenAI, Azure, Groq, Together, Fireworks, OpenRouter, DeepSeek, Mistral, xAI, Ollama, LM Studio, and vLLM. - Three structured output modes:
json_schemastrict mode,toolsfunction calling, and prompted JSON repair fallback. - Endpoint capability caching per
baseUrl+ model. - SSE token streaming.
- Targets
- Anthropic adapter (
AnthropicProvider):- Targets
POST {baseUrl}/v1/messageswithtools+tool_choiceforced function calling. - Direct decoding of
tool_usecontent blocks andcontent_block_deltaSSE streaming.
- Targets
- Custom adapter (
CustomProvider):- Allows wrapping arbitrary functions or enterprise API gateways into an
AiProvider.
- Allows wrapping arbitrary functions or enterprise API gateways into an
- Fallback engine (
ProviderChain):- Ordered fallback with exact failure escalation: handles unconfigured providers, offline/network errors, 429 rate limits (with backoff), 5xx server errors (with retry), and 401/403 auth errors (loud warnings).
- Terminal fallback to on-device Gemma with configuration warnings when an offline floor is absent.
- Per-provider circuit breaker to stop hammering down endpoints.
preferLocalmode prioritizing on-device inference before cloud escalation.
- Privacy & security controls:
allowCloudEgress: falseby default, ensuring zero scraped content is sent off-device without explicit opt-in.KeySanitizerredacts sensitive API keys and bearer tokens from all logs and error strings.- Published comprehensive security guide in
doc/PROVIDERS.mdemphasizing the backend proxy pattern.
- Cost & usage accounting (
cost_tracker.dart):ModelPricingper-model price catalog.UsageSessionaggregating prompt/completion tokens, dollar spend, and savings from deterministic short-circuits.
2.0.0-dev.4 - 2026-09-02 #
Phase 3: AI Provider layer and on-device Gemma integration.
Added #
flutter_gemmaintegration: addedflutter_gemma: ^1.7.0to library dependencies, with opt-in inference engines (flutter_gemma_litertlmandflutter_gemma_mediapipe) in the demo app.AiProvidercontract (lib/src/ai/ai_provider.dart):- Defines
extract(Schema, content)as the primary seam rather than simple string completions. - Full capability profiling with
AiCapabilities, execution metrics withTokenUsage, and typedAiResult.
- Defines
FakeAiProvider(lib/src/ai/fake_ai_provider.dart):- Scripted, deterministic mock provider for CI and offline unit testing without requiring a 550 MB model download.
GemmaProvider(lib/src/ai/providers/gemma_provider.dart):- Real on-device provider utilizing
flutter_gemmawith native function calling.
- Real on-device provider utilizing
ModelManager&GemmaModelscatalogue (lib/src/ai/model_manager.dart):- Model lifecycle management (
install,uninstallModel,isModelInstalled,listInstalledModels,getStorageInfo). - Curated catalogue: Gemma 3 1B, FunctionGemma 270M, Qwen3 0.6B, Gemma 4 E2B (excluding Gemma 3 270M).
- Gated repository error mapping: maps 401 and 403 HTTP errors to clear Hugging Face token and access agreement instructions.
- Model lifecycle management (
- Schema-as-tool bridge (
lib/src/ai/tool_bridge.dart):- Translates
SchemaDSL toToolspecifications with Draft-07 JSON Schema parameters. - Sets
ToolChoice.requiredand parses structured arguments fromFunctionCallResponse.args. - Self-healing retry feedback loop when validation fails.
- Translates
- Extraction strategies & provenance (
lib/src/ai/extractor.dart):- Object extraction over BM25-ranked top-K chunks.
- Map-reduce list extraction with chunking and configurable deduplication.
- Strict provenance guarantee: deterministic structured data always takes priority over AI guesses.
- Short-circuiting: zero inference when structured data already satisfies the schema.
- Graceful degradation on timeout.
- Provider-derived token budget (
lib/src/reduce/budget.dart):TokenBudget.fromCapabilities()andTokenBudget.fromProvider().
- Public API:
ScrapedPage.extractWithAi()andScrapedPage.extractAsync().
2.0.0-dev.3 - 2026-09-02 #
Phase 2: deterministic reduction and structured data harvesting. Shrinks pages deterministically and satisfies many schemas with zero inference.
Added #
- Schema DSL (
Field,Schema) with validation, automatic type coercion, and Draft-07 JSON Schema generation (Schema.toJsonSchema()). - Structured data harvesters:
JsonLdHarvester: parses<script type="application/ld+json">, handles@graphand arrays.MicrodataHarvester: W3C HTML Microdata (itemscope,itemtype,itemprop).RdfaHarvester: W3C RDFa Lite (vocab,typeof,property).OpenGraphHarvester: OpenGraph, Twitter Cards, canonical links, standard meta tags.StructuredMapper: maps Schema.org types onto target schemas with field synonym resolution and provenance reporting (ExtractionCoverage).
- Readability scoring engine (
ReadabilityScorer) with DOM node scoring, link density penalties, chrome filtering, sibling inclusion, and image preservation. - GFM Markdown serializer (
MarkdownWriter) withMarkdownOptionsand real GitHub-Flavoured table rendering withthdetection and pipe escaping. - Chunking & ranking pipeline:
TokenEstimator: 4 chars/token heuristic.Chunker: structure-preserving chunking that never splits tables, code blocks, or lists mid-structure.Bm25Ranker: BM25 relevance scoring with query synonym expansion.TokenBudget: context window management with reserved generation headroom.
- Tier-1 Public API:
AiScrapper.open()andAiScrapper.fromHtml()returningScrapedPage.ScrapedPage.article(),.markdown,.plainText,.metadata,.links,.images,.tables,.extract(schema).
- Golden fixture corpus grown to 15 fixtures (added
commerce_rdfa,recipe_jsonld,event_microdata,article_blog_sidebar,jobs_jsonld).
Fixed #
- Fabricated currency bug: money parsing detects real symbols and codes (
Β£->GBP,β¬->EUR,$->USD,Β₯->JPY).β¬99never becomes$99. - Phone extraction: strict format validation requiring real international/national phone shapes; rejects dates, SKUs, and prices.
2.0.0-dev.2 - 2026-09-02 #
Phase 1: the parsing core is replaced. Every extraction path now runs through
package:html β a real HTML5 parser β instead of regular expressions.
Fixed #
- Nested containers no longer truncate.
<div>(.*?)</div>stopped at the first closing tag, so querying any container returned a fragment and silently dropped the rest. - Class filters no longer leak across the document. The regex lookahead ran with
dotAll, so it scanned the whole remaining page β an element with no class at all matched a class filter because an unrelated later element carried it. Wrong data, no error. - Timeouts are caught. The package declared its own
TimeoutException, which shadoweddart:async's inside the same library, soon TimeoutExceptionnever matched what.timeout()throws. Every timeout was mislabelled as an unexpected network error. - Backoff is exponential. It computed
initialDelay Γ (multiplier Γ attempt)β linear β while documenting exponential. Jitter added, so clients no longer retry a struggling host in lockstep. - Group-less regex patterns work.
queryWithRegexread group 1 unconditionally, so a pattern of only non-capturing(?:β¦)groups threwRangeError, relabelled as "Failed to parse HTML" β pointing the caller at their markup instead of the group index. - Regex is case-sensitive by default, matching Dart's own
RegExp. 1.x forced case-insensitivity with no opt-out, so[A-Z][a-z]+also matched lowercase. - Non-breaking spaces are folded.
decodes to U+00A0 and survived whitespace normalisation, sotext.contains('12 %')failed against12\u{00A0}%invisibly. - The size limit works. It was checked after the whole body had been buffered into memory; it now aborts mid-download.
- The cache is durable. It lived in
Directory.systemTemp, which the OS may clear at any time, and rewrote every entry into one JSON file on each write.
Added #
HtmlDocument/HtmlNodewith CSS selectors,blockText, and URL resolution that honours<base href>.SelectorGuard, which refuses selectorspackage:htmlanswers wrongly. Structural pseudo-classes likeli:nth-child(2)return zero matches on markup that plainly contains them; a confidently empty result is worse than a refusal, so these raiseInvalidSelectorExceptionnaming the workaround.RegexTarget, so a pattern can run against visible text instead of markup β the fix for URLs captured with a trailing</p>.robots.txtsupport, per-host rate limiting and a truthfulUser-Agent, all on by default.- Conditional requests with
ETag/Last-Modified, so an unchanged page costs a304. - Charset detection: BOM, then
Content-Type, then<meta charset>. 1.x read only the header, so pages declaring encoding in markup came back as mojibake. CancellationToken. 1.x'scancel()completed an error on aCompleternobody awaited, producing an unhandled async error rather than stopping the work.- A 10-page golden fixture corpus and
tool/capture_fixture.dart.
Changed β breaking #
TimeoutExceptionβScraperTimeoutException(the old name shadoweddart:async's).ScraperExceptionis nowsealed, withInvalidUrlException,HttpStatusException,RobotsDisallowedException,CancelledExceptionandInvalidSelectorExceptionsplit out. Every exception carries auserMessagesafe to show a person.ContentFormatterandSmartExtractortake anHtmlDocument, not aString.ContentFormatter.toCleanHtml,removeClutterandextractReadableTextremoved.CacheManagerreplaced byCacheStore.estimateReadingTimereports seconds rather than rounding up to whole minutes.- The platform gate no longer inspects
Platform.environmentforFLUTTER_TEST. Tests inject aPlatformInfoinstead, so no test awareness ships in production code.
Removed #
- Price extraction. It stamped
$on every match regardless of currency, soβ¬99came back as$99. Fabricating currency is worse than returning nothing; real money parsing arrives with the structured-data work. - Phone extraction. Its pattern matched dates, SKUs and IDs as freely as phone numbers. Returning when it can be done with region-aware parsing.
2.0.0-dev.1 - 2026-09-02 #
Phase 0 of the 2.0 rebuild: the package is renamed and correctly shaped. No scraping behaviour changed in this release β the 7 inherited test failures fail identically before and after, which is the evidence for that claim.
Breaking #
- Renamed
flutter_scrapperβflutter_ai_scrapper. - Single entrypoint.
lib/mobile_scraper.dartandlib/flutter_mobile_scraper.dartare replaced bypackage:flutter_ai_scrapper/flutter_ai_scrapper.dart. Everything else moved underlib/src/and is no longer importable directly. ScraperViewModelmoved to the example app. A package should not ship aChangeNotifierbound to a particular state-management library. Purpose-built widgets arrive in a later phase.provideris no longer a dependency, so the package imposes no state-management choice.- Platform floors raised to Android minSdk 24 (was API 21) and iOS 15.0 (was iOS 12), as
required by
flutter_gemma1.7.0. The old floors were never achievable alongside on-device AI. - SDK floors raised to Dart >=3.12.0 and Flutter >=3.44.0.
- Android and iOS only, now declared in
pubspec.yamlso pub.flutter-io.cn states it rather than leaving consumers to hit it at runtime.
Changed #
- Default
User-Agentis now truthful and carries a contact URL. - Analyzer tightened (
strict-casts,strict-raw-types,strict-inference, plus correctness lints). Issue count went from 194 to 0. - The demo app moved to
example/, and the staleexample_app/β whose own widget test never compiled β was removed.
Known issues #
7 inherited tests fail, all traced to the regex parsing engine that Phase 1 replaces. Three are
cases where the test is right and the library is wrong. See test/KNOWN_FAILURES.md.
1.1.0 - 2025-10-09 #
Changed #
- Upgraded package version to 1.1.0
- Updated dependencies to latest versions
0.1.0 - 2024-01-15 #
Added #
- Initial release of flutter_scrapper
- Basic HTML scraping functionality for mobile platforms
- Support for tag-based content extraction
- Support for regex-based content extraction
- Smart content extraction with auto-detection
- High-performance caching system
- Content formatting (plain text, markdown, clean HTML, readable)
- Comprehensive error handling
- Platform validation (Android/iOS only)
- Retry mechanism with exponential backoff
- Configurable timeout and headers
- Complete test coverage
Features #
- Smart Content Extraction: Auto-detect titles, descriptions, images, prices, and more
- High-Performance Caching: 50x faster repeated requests with intelligent caching
- Professional Content Formatting: Clean text, Markdown, readability mode
- Production Ready: Error handling, retry logic, resource management
Platform Support #
- β Android
- β iOS
- β Web (by design)
- β Desktop (by design)
Documentation #
- Comprehensive README with examples
- API documentation with dartdoc comments
- MVVM architecture explanation
- Usage examples and best practices