# Crawl4AI Extraction Strategy Playbook (v0.8.x)
## When to use Crawl4AI (vs requests/BeautifulSoup)
Use Crawl4AI when:
- You need clean, LLM-ready content from webpages (especially for research/RAG/reference files).
- The page is JavaScript-heavy and normal requests/BeautifulSoup scraping likely fails.
- You need structured JSON from repeated elements (e.g., product listings, docs sections, job posts, changelogs, directory pages).
- You want a cheaper/non-LLM extraction first, with a fallback to LLM only when needed.
## Reliability rule
- Always check `result.success` before trusting outputs.
## Prefer strategy order
1) Markdown extraction (for reference/RAG)
2) LLM-free structured JSON:
- CSS/XPath schema extraction for repeated structured elements
- RegexExtractionStrategy for simple fields (URLs/emails/dates/currency/phone/IDs/etc.)
3) LLMExtractionStrategy only when content is unstructured/semantic interpretation is required.
- Note: LLM extraction can be slower and costlier than schema/regex.
## Minimal async crawler baseline (Markdown output)
```python
import asyncio
from crawl4ai import AsyncWebCrawler, CrawlerRunConfig
from crawl4ai.markdown_generation_strategy import DefaultMarkdownGenerator
async def main():
config = CrawlerRunConfig(markdown_generator=DefaultMarkdownGenerator())
async with AsyncWebCrawler() as crawler:
result = await crawler.arun("https://example.com", config=config)
if result.success:
print(result.markdown)
else:
print("Crawl failed:", result.error_message)
if __name__ == "__main__":
asyncio.run(main())
```
## LLM-friendly Markdown vs filtered “fit_markdown”
- Crawl4AI can provide both:
- `result.markdown` (raw/unfiltered markdown)
- `fit_markdown` when content filters are used (filtered “fit” markdown)
(Use filtered markdown when you want fewer tokens for downstream LLM tasks; the LLM extraction docs explicitly support `input_format="fit_markdown"`.)
## LLM-Free JSON extraction (schema-based): CSS or XPath
Use when the page has repeated structured elements.
### JsonCssExtractionStrategy (CSS)
- Strategy uses:
- `baseSelector`: container for each repeated item
- `fields`: per-item fields with CSS selectors and `type`
- Example structure (from docs):
```python
schema = {
"name": "Crypto Prices",
"baseSelector": "div.crypto-row",
"fields": [
{"name": "coin_name", "selector": "h2.coin-name", "type": "text"},
{"name": "price", "selector": "span.coin-price", "type": "text"},
],
}
extraction_strategy = JsonCssExtractionStrategy(schema, verbose=True)
config = CrawlerRunConfig(
cache_mode=CacheMode.BYPASS,
extraction_strategy=extraction_strategy,
)
```
### JsonXPathExtractionStrategy (XPath)
Same concept as CSS version but using XPath selectors.
### raw:// scheme (for local HTML testing)
- Crawl4AI supports passing dummy HTML directly via `raw://<html_string>`.
- This is shown in the XPath example.
## LLM-Free JSON extraction: RegexExtractionStrategy
Use when you only need fast pattern extraction (emails/phones/URLs/dates/currency/etc.).
### Built-in patterns (IntFlag)
- `RegexExtractionStrategy.Url`
- `RegexExtractionStrategy.Email`
- `RegexExtractionStrategy.PhoneUS`, `RegexExtractionStrategy.PhoneIntl`
- `RegexExtractionStrategy.DateIso`, `RegexExtractionStrategy.DateUS`
- `RegexExtractionStrategy.Currency`, `RegexExtractionStrategy.Number`, `RegexExtractionStrategy.Uuid`, etc.
### Simple example
```python
strategy = RegexExtractionStrategy(
pattern = RegexExtractionStrategy.Email | RegexExtractionStrategy.Url
)
config = CrawlerRunConfig(extraction_strategy=strategy)
result = await crawler.arun(url="https://example.com", config=config)
if result.success:
data = json.loads(result.extracted_content)
```
### Regex match output shape
Returns a JSON array of matches like:
```json
[
{
"url": "https://example.com",
"label": "email",
"value": "contact@example.com",
"span": [145, 163]
}
]
```
### LLM-assisted regex pattern generation (one-time)
- RegexExtractionStrategy includes `generate_pattern(label, html, query, llm_config)`.
- Workflow described: fetch sample HTML, generate pattern once via LLM, save to disk, then extract with regex only.
## LLM extraction: LLMExtractionStrategy
Use when:
- content is unstructured
- you need semantic interpretation / reorganization / knowledge-graph style extraction
### Key facts from docs
- Provider-agnostic via LiteLLM using `LLMConfig(provider="<provider>/<model>", api_token=..., base_url=optional)`.
- LLM-based extraction can be slower and costlier than schema-based.
- Strategy must be placed in `CrawlerRunConfig(extraction_strategy=...)` (not passed directly as a param to `arun()`).
### extraction_type
- `extraction_type="schema"`: model returns JSON conforming to a Pydantic-derived schema.
- `extraction_type="block"`: model returns freeform text or smaller JSON structures; library collects.
### input_format
Controls what the LLM receives:
- `"markdown"` (default)
- `"fit_markdown"`
- `"html"`
### chunking parameters
- `chunk_token_threshold` (max tokens per chunk)
- `overlap_rate` (e.g., 0.1 for 10% overlap)
- `apply_chunking` (bool)
### Required/typical parameters inside LLMExtractionStrategy
From the docs:
- `llm_config: LLMConfig`
- `schema: dict` (when `extraction_type="schema"`)
- `extraction_type: "schema" | "block"`
- `instruction: str`
- optional chunking fields (`chunk_token_threshold`, `overlap_rate`, `apply_chunking`)
- `input_format: "markdown" | "fit_markdown" | "html"`
- optional `extra_args`
### Minimal pattern
```python
import os, json
from pydantic import BaseModel
from crawl4ai import (
AsyncWebCrawler, BrowserConfig, CrawlerRunConfig,
CacheMode, LLMConfig, LLMExtractionStrategy
)
class Product(BaseModel):
name: str
price: str
async def main():
llm_strategy = LLMExtractionStrategy(
llm_config=LLMConfig(
provider="openai/gpt-4o-mini",
api_token=os.getenv("OPENAI_API_KEY"),
),
schema=Product.model_json_schema(),
extraction_type="schema",
instruction="Extract all product objects with 'name' and 'price'.",
apply_chunking=True,
input_format="markdown",
extra_args={"temperature": 0.0, "max_tokens": 800},
verbose=True,
)
crawl_config = CrawlerRunConfig(
extraction_strategy=llm_strategy,
cache_mode=CacheMode.BYPASS,
)
async with AsyncWebCrawler(config=BrowserConfig(headless=True)) as crawler:
result = await crawler.arun(url="https://example.com/products", config=crawl_config)
if result.success:
data = json.loads(result.extracted_content)
print(data)
llm_strategy.show_usage()
else:
print("Error:", result.error_message)
import asyncio
if __name__ == "__main__":
asyncio.run(main())
```
## LLM output handling
- When `extraction_type="schema"`, the docs recommend parsing/validating the JSON output.
- `llm_strategy.show_usage()` prints token usage when provided by the provider.
## Strategy placement constraint
- Docs explicitly state: strategy definitions belong inside `CrawlerRunConfig`, not as direct parameters to `arun()`.
## Sibling layout handling for schema extraction (CSS/XPath)
If an item’s data is split across sibling elements (not descendants of a base container), schema supports per-field `source` to navigate to a sibling before applying that field’s selector.
Syntax shown:
- `"source": "+ <selector>"`
Example from docs (Hacker News):
```json
{"name": "score", "selector": "span.score", "type": "text", "source": "+ tr"}
```
## JS-heavy pages
- Crawl4AI supports JS execution and dynamic content rendering via its browser integration (JS execution described in examples using `js_code` in `CrawlerRunConfig`).
- For structured extraction on JS-rendered sections, docs show passing `js_code` to click tabs and wait.
(See separate note in install/dynamic-pages file about how to use async + js_code; the code example shown in Crawl4AI README uses `run_config = CrawlerRunConfig(js_code=[...])`.)
Crawl4AI Webpage → Clean Markdown/JSON
Description
Turns webpages into clean, LLM-ready Markdown or structured JSON using the Crawl4AI Python library. Use when the user asks to scrape/convert a URL into “clean markdown for RAG”, “reference file markdown”, “structured JSON for repeated items”, or when pages are “JavaScript-heavy” / “dynamic” and requests + BeautifulSoup won’t reliably capture content. Also use when the user asks for “async crawl”, “run Crawl4AI with js_code”, or “extract with CSS/XPath/regex/LLM strategy”. Trigger keywords: crawl4ai, AsyncWebCrawler, CrawlerRunConfig, js_code, DefaultMarkdownGenerator, fit_markdown, JsonCssExtractionStrategy, JsonXPathExtractionStrategy, RegexExtractionStrategy, LLMExtractionStrategy, extracted_content, result.success. Prefer Crawl4AI over requests/BS unless the page is trivially static and the user explicitly wants lightweight HTML parsing.
When to Use
Use this skill when the agent needs Crawl4AI-driven extraction from URLs into LLM-ready Markdown or structured JSON, especially for JS/dynamic pages or when choosing between Markdown, CSS/XPath JSON schemas, regex, and LLM extraction strategies.
Use Cases
- Turn documentation/blog pages into clean Markdown for RAG/reference files
- Extract repeated entities (products, jobs, changelog entries, directory listings) into structured JSON
- Scrape JavaScript-heavy pages by running js_code and/or using a persistent browser profile
- Choose the cheapest reliable extraction strategy (CSS/XPath vs regex vs LLM) with reliability checks
Bundle Explorer
3 files across 1 folder. Click a file to inspect its contents.
# Crawl4AI Install & Dynamic Crawling (async + JS)
## Install (Python)
- Basic install:
- `pip install -U crawl4ai`
- If you need pre-release:
- `pip install crawl4ai --pre`
- After installing, run post-install setup:
- `crawl4ai-setup`
- Verify installation:
- `crawl4ai-doctor`
## Playwright dependencies
- Crawl4AI uses Playwright for web crawling (async version).
- If Playwright-related errors occur, install browsers manually:
- `playwright install`
- or: `python -m playwright install chromium`
## Minimal async crawl
```python
import asyncio
from crawl4ai import AsyncWebCrawler
async def main():
async with AsyncWebCrawler() as crawler:
result = await crawler.arun(url="https://www.nbcnews.com/business")
print(result.markdown)
if __name__ == "__main__":
asyncio.run(main())
```
## JS-heavy pages: use the browser and run custom JS
Crawl4AI supports executing JavaScript and waiting for dynamic content. Docs show using `CrawlerRunConfig(js_code=[...])`.
Example: click through tabs to reveal content, then extract structured data without LLMs:
```python
import asyncio, json
from crawl4ai import (
AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode,
JsonCssExtractionStrategy
)
async def main():
schema = {
"name": "KidoCode Courses",
"baseSelector": "section.charge-methodology .w-tab-content > div",
"fields": [
{"name": "section_title", "selector": "h3.heading-50", "type": "text"},
{"name": "section_description", "selector": ".charge-content", "type": "text"},
{"name": "course_name", "selector": ".text-block-93", "type": "text"},
{"name": "course_description", "selector": ".course-content-text", "type": "text"},
{"name": "course_icon", "selector": ".image-92", "type": "attribute", "attribute": "src"},
],
}
extraction_strategy = JsonCssExtractionStrategy(schema, verbose=True)
browser_config = BrowserConfig(headless=False, verbose=True)
run_config = CrawlerRunConfig(
extraction_strategy=extraction_strategy,
js_code=["""
(async () => {
const tabs = document.querySelectorAll(
"section.charge-methodology .tabs-menu-3 > div"
);
for (let tab of tabs) {
tab.scrollIntoView();
tab.click();
await new Promise(r => setTimeout(r, 500));
}
})();
"""],
cache_mode=CacheMode.BYPASS,
)
async with AsyncWebCrawler(config=browser_config) as crawler:
result = await crawler.arun(
url="https://www.kidocode.com/degrees/technology",
config=run_config,
)
companies = json.loads(result.extracted_content)
print(f"Successfully extracted {len(companies)} companies")
print(json.dumps(companies[0], indent=2))
if __name__ == "__main__":
asyncio.run(main())
```
## Browser/session persistence (persistent user profile)
Docs show `BrowserConfig(user_data_dir=..., use_persistent_context=True)` with `magic=True` when crawling:
```python
import os
from pathlib import Path
import asyncio
from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, CacheMode
async def test_news_crawl():
user_data_dir = os.path.join(Path.home(), ".crawl4ai", "browser_profile")
os.makedirs(user_data_dir, exist_ok=True)
browser_config = BrowserConfig(
verbose=True,
headless=True,
user_data_dir=user_data_dir,
use_persistent_context=True,
)
run_config = CrawlerRunConfig(cache_mode=CacheMode.BYPASS)
async with AsyncWebCrawler(config=browser_config) as crawler:
url = "ADDRESS_OF_A_CHALLENGING_WEBSITE"
result = await crawler.arun(url, config=run_config, magic=True)
print(f"Content length: {len(result.markdown)}")
if __name__ == "__main__":
asyncio.run(test_news_crawl())
```
## Docker quick test (self-hosted API)
The README describes a Docker image exposing endpoints like `/crawl` and `/task/{task_id}`.
Run container:
- `docker pull unclecode/crawl4ai:latest`
- `docker run -d -p 11235:11235 --name crawl4ai --shm-size=1g unclecode/crawl4ai:latest`
Submit crawl job (POST `/crawl`):
```python
import requests
response = requests.post(
"http://localhost:11235/crawl",
json={"urls": ["https://example.com"], "priority": 10}
)
if response.status_code == 200:
if "results" in response.json():
results = response.json()["results"]
for result in results:
print(result)
else:
task_id = response.json()["task_id"]
result = requests.get(f"http://localhost:11235/task/{task_id}")
```
(For monitoring dashboard/playground URLs, the README states: `http://localhost:11235/dashboard` and `http://localhost:11235/playground`.)
---
name: crawl4ai-webpage-to-markdown-json
description: "Turns webpages into clean, LLM-ready Markdown or structured JSON using the Crawl4AI Python library. Use when the user asks to scrape/convert a URL into “clean markdown for RAG”, “reference file markdown”, “structured JSON for repeated items”, or when pages are “JavaScript-heavy” / “dynamic” and requests + BeautifulSoup won’t reliably capture content. Also use when the user asks for “async crawl”, “run Crawl4AI with js_code”, or “extract with CSS/XPath/regex/LLM strategy”. Trigger keywords: crawl4ai, AsyncWebCrawler, CrawlerRunConfig, js_code, DefaultMarkdownGenerator, fit_markdown, JsonCssExtractionStrategy, JsonXPathExtractionStrategy, RegexExtractionStrategy, LLMExtractionStrategy, extracted_content, result.success. Prefer Crawl4AI over requests/BS unless the page is trivially static and the user explicitly wants lightweight HTML parsing."
---
Crawl4AI guidance for converting webpages to clean Markdown or structured JSON.
Workflow
1) Decide the extraction approach.
- If the goal is “LLM-ready Markdown / RAG / reference files”, plan to use DefaultMarkdownGenerator and return result.markdown or fit_markdown.
- If the goal is “structured JSON for repeated items” (lists of cards/rows/sections), plan schema-based JSON first via CSS or XPath.
- If you only need a few fast fields (emails/urls/phones/dates/currency/ids), plan RegexExtractionStrategy.
- If the goal requires semantic interpretation/unstructured reformatting, plan LLMExtractionStrategy.
2) Prefer Crawl4AI over requests/BeautifulSoup when:
- The page is JS-heavy/dynamic, content loads after interactions, or static HTML misses the needed text.
- You need consistent cleaning into LLM-ready output.
Use when the user requests “clean markdown” or “structured extraction” from a URL.
3) Install and verify before coding.
- Run: pip install -U crawl4ai
- Run: crawl4ai-setup
- Run: crawl4ai-doctor
- If Playwright issues: run playwright install (or python -m playwright install chromium).
(Read [references/crawl4ai-install-and-dynamic-crawling.md](references/crawl4ai-install-and-dynamic-crawling.md) when setting up/installing or debugging Playwright/dynamic crawling.)
4) Use the async crawling baseline.
- Use AsyncWebCrawler in an asyncio program.
- Run crawler.arun(url, config=CrawlerRunConfig(...)).
- Always check result.success before using result.markdown or result.extracted_content.
(Read [references/crawl4ai-extraction-strategy-playbook.md](references/crawl4ai-extraction-strategy-playbook.md) when selecting Markdown vs JSON strategies, ordering strategies, and enforcing result.success checks.)
5) Generate LLM-ready Markdown for RAG/reference files.
- Configure CrawlerRunConfig(markdown_generator=DefaultMarkdownGenerator()).
- After arun: if result.success, return result.markdown (or use fit_markdown when token reduction/filtered content is required).
- Prefer fit_markdown when downstream LLM context budget is tight.
6) Handle JavaScript-heavy or interaction-revealed content.
- Use CrawlerRunConfig(js_code=[...]) to run browser-side JS (e.g., click tabs, expand accordions, scroll to trigger lazy loads).
- If needed, use BrowserConfig(headless=..., user_data_dir=..., use_persistent_context=True) to persist sessions.
(Read [references/crawl4ai-install-and-dynamic-crawling.md](references/crawl4ai-install-and-dynamic-crawling.md) when the page requires dynamic JS, js_code usage, or persistent browser profiles.)
7) Produce structured JSON without LLM first.
- For repeated structured items: use JsonCssExtractionStrategy or JsonXPathExtractionStrategy with a schema defining baseSelector and fields.
- Place extraction_strategy in CrawlerRunConfig(extraction_strategy=...).
- After arun: if result.success, parse result.extracted_content as JSON.
8) Use regex only for simple patterns.
- Use RegexExtractionStrategy with built-in patterns (Email/Url/Phone/Date/Currency/Number/Uuid, etc.).
- Parse result.extracted_content as JSON when result.success.
9) Use LLMExtractionStrategy only when needed.
- Use LLMExtractionStrategy(...), and place it in CrawlerRunConfig(extraction_strategy=...); do not pass it directly to arun().
- Choose extraction_type:
* “schema” when you need strict JSON conforming to a schema.
* “block” when you want freeform text/smaller structures.
- Choose input_format among markdown/fit_markdown/html.
- Configure llm_config (provider/model) from your externally prepared auth environment.
(Read [references/crawl4ai-extraction-strategy-playbook.md](references/crawl4ai-extraction-strategy-playbook.md) when deciding between CSS/XPath vs regex vs LLM, and when enforcing placement + reliability checks.)
Constraints / edge cases
- Never trust output until result.success is True. If false, return the error (result.error_message) and suggest retry with js_code or a different strategy.
- Strategy ordering rule: Markdown first for reference/RAG; schema JSON next (CSS/XPath); regex for simple fields; LLM last.
- If extraction fails on a JS page, add js_code to reveal the content before extracting.
- For repeated structured content, prefer CSS/XPath over LLM for speed/cost.
Concrete I/O expectations
- Markdown path: return a string from result.markdown (or fit_markdown if configured/used).
- JSON path: return parsed JSON from json.loads(result.extracted_content) after result.success.
Example output mapping
- User asks: “Convert this docs URL into clean markdown for my RAG reference.” → Use MarkdownGenerator; return result.markdown/fit_markdown.
- User asks: “Extract product listings (name, price, url) into JSON.” → Use JsonCssExtractionStrategy or JsonXPathExtractionStrategy; return JSON.
- User asks: “Find all emails/phones/urls on this page.” → Use RegexExtractionStrategy; return matches.
- User asks: “Summarize each section into a structured knowledge graph.” → Use LLMExtractionStrategy (schema if strict), with fit_markdown input.
SKILL.md Content
---
name: crawl4ai-webpage-to-markdown-json
description: "Turns webpages into clean, LLM-ready Markdown or structured JSON using the Crawl4AI Python library. Use when the user asks to scrape/convert a URL into “clean markdown for RAG”, “reference file markdown”, “structured JSON for repeated items”, or when pages are “JavaScript-heavy” / “dynamic” and requests + BeautifulSoup won’t reliably capture content. Also use when the user asks for “async crawl”, “run Crawl4AI with js_code”, or “extract with CSS/XPath/regex/LLM strategy”. Trigger keywords: crawl4ai, AsyncWebCrawler, CrawlerRunConfig, js_code, DefaultMarkdownGenerator, fit_markdown, JsonCssExtractionStrategy, JsonXPathExtractionStrategy, RegexExtractionStrategy, LLMExtractionStrategy, extracted_content, result.success. Prefer Crawl4AI over requests/BS unless the page is trivially static and the user explicitly wants lightweight HTML parsing."
---
Crawl4AI guidance for converting webpages to clean Markdown or structured JSON.
Workflow
1) Decide the extraction approach.
- If the goal is “LLM-ready Markdown / RAG / reference files”, plan to use DefaultMarkdownGenerator and return result.markdown or fit_markdown.
- If the goal is “structured JSON for repeated items” (lists of cards/rows/sections), plan schema-based JSON first via CSS or XPath.
- If you only need a few fast fields (emails/urls/phones/dates/currency/ids), plan RegexExtractionStrategy.
- If the goal requires semantic interpretation/unstructured reformatting, plan LLMExtractionStrategy.
2) Prefer Crawl4AI over requests/BeautifulSoup when:
- The page is JS-heavy/dynamic, content loads after interactions, or static HTML misses the needed text.
- You need consistent cleaning into LLM-ready output.
Use when the user requests “clean markdown” or “structured extraction” from a URL.
3) Install and verify before coding.
- Run: pip install -U crawl4ai
- Run: crawl4ai-setup
- Run: crawl4ai-doctor
- If Playwright issues: run playwright install (or python -m playwright install chromium).
(Read [references/crawl4ai-install-and-dynamic-crawling.md](references/crawl4ai-install-and-dynamic-crawling.md) when setting up/installing or debugging Playwright/dynamic crawling.)
4) Use the async crawling baseline.
- Use AsyncWebCrawler in an asyncio program.
- Run crawler.arun(url, config=CrawlerRunConfig(...)).
- Always check result.success before using result.markdown or result.extracted_content.
(Read [references/crawl4ai-extraction-strategy-playbook.md](references/crawl4ai-extraction-strategy-playbook.md) when selecting Markdown vs JSON strategies, ordering strategies, and enforcing result.success checks.)
5) Generate LLM-ready Markdown for RAG/reference files.
- Configure CrawlerRunConfig(markdown_generator=DefaultMarkdownGenerator()).
- After arun: if result.success, return result.markdown (or use fit_markdown when token reduction/filtered content is required).
- Prefer fit_markdown when downstream LLM context budget is tight.
6) Handle JavaScript-heavy or interaction-revealed content.
- Use CrawlerRunConfig(js_code=[...]) to run browser-side JS (e.g., click tabs, expand accordions, scroll to trigger lazy loads).
- If needed, use BrowserConfig(headless=..., user_data_dir=..., use_persistent_context=True) to persist sessions.
(Read [references/crawl4ai-install-and-dynamic-crawling.md](references/crawl4ai-install-and-dynamic-crawling.md) when the page requires dynamic JS, js_code usage, or persistent browser profiles.)
7) Produce structured JSON without LLM first.
- For repeated structured items: use JsonCssExtractionStrategy or JsonXPathExtractionStrategy with a schema defining baseSelector and fields.
- Place extraction_strategy in CrawlerRunConfig(extraction_strategy=...).
- After arun: if result.success, parse result.extracted_content as JSON.
8) Use regex only for simple patterns.
- Use RegexExtractionStrategy with built-in patterns (Email/Url/Phone/Date/Currency/Number/Uuid, etc.).
- Parse result.extracted_content as JSON when result.success.
9) Use LLMExtractionStrategy only when needed.
- Use LLMExtractionStrategy(...), and place it in CrawlerRunConfig(extraction_strategy=...); do not pass it directly to arun().
- Choose extraction_type:
* “schema” when you need strict JSON conforming to a schema.
* “block” when you want freeform text/smaller structures.
- Choose input_format among markdown/fit_markdown/html.
- Configure llm_config (provider/model) from your externally prepared auth environment.
(Read [references/crawl4ai-extraction-strategy-playbook.md](references/crawl4ai-extraction-strategy-playbook.md) when deciding between CSS/XPath vs regex vs LLM, and when enforcing placement + reliability checks.)
Constraints / edge cases
- Never trust output until result.success is True. If false, return the error (result.error_message) and suggest retry with js_code or a different strategy.
- Strategy ordering rule: Markdown first for reference/RAG; schema JSON next (CSS/XPath); regex for simple fields; LLM last.
- If extraction fails on a JS page, add js_code to reveal the content before extracting.
- For repeated structured content, prefer CSS/XPath over LLM for speed/cost.
Concrete I/O expectations
- Markdown path: return a string from result.markdown (or fit_markdown if configured/used).
- JSON path: return parsed JSON from json.loads(result.extracted_content) after result.success.
Example output mapping
- User asks: “Convert this docs URL into clean markdown for my RAG reference.” → Use MarkdownGenerator; return result.markdown/fit_markdown.
- User asks: “Extract product listings (name, price, url) into JSON.” → Use JsonCssExtractionStrategy or JsonXPathExtractionStrategy; return JSON.
- User asks: “Find all emails/phones/urls on this page.” → Use RegexExtractionStrategy; return matches.
- User asks: “Summarize each section into a structured knowledge graph.” → Use LLMExtractionStrategy (schema if strict), with fit_markdown input.