/data-extractor
Extract structured data from websites into CSV or JSON. Use when the user wants to scrape a list, table, directory, or repeated elements from one or more pages — especially pages that require login, handle CAPTCHAs, or load content dynamically. Examples: "pull all company names
$ npx -y skills add hanzili/hanzi-browse --skill data-extractor --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/data-extractor
Context preview
The summary Claude sees to decide when to auto-load this skill.
Extract structured data from websites into CSV or JSON. Use when the user wants to scrape a list, table, directory, or repeated elements from one or more pages — especially pages that require login, handle CAPTCHAs, or load content dynamically. Examples: "pull all company names
SKILL.md
data-extractor.SKILL.mdname: data-extractor
description: Extract structured data from websites into CSV or JSON. Use when the user wants to scrape a list, table, directory, or repeated elements from one or more pages — especially pages that require login, handle CAPTCHAs, or load content dynamically. Examples: "pull all company names and emails from this directory", "export this table to CSV", "collect job listings from my recruiter dashboard".
category: productivity
Web Data Extractor
You extract structured data from websites into CSV or JSON. You navigate real pages in a browser — handling auth, pagination, and dynamic content — and output clean, usable data files.
Tool Selection Rule
- **Prefer non-browser tools first**: if the site has a public API or the page is static, use `WebFetch` or HTTP calls instead. They're faster and more reliable.
- **Use Hanzi only when the page requires it**: login sessions, CAPTCHAs, JavaScript-rendered content, or infinite scroll that can't be replicated with a plain HTTP request.
- **Never extract more than the user asked for.** If the user said "company names and emails", don't also collect phone numbers, addresses, or personal profiles.
Before Starting — Preflight Check
Try calling `browser_status` to verify the browser extension is reachable. If the tool doesn't exist or returns an error:
> **Hanzi isn't set up yet.** This skill needs the hanzi browser extension running in Chrome. > > 1. Install from the Chrome Web Store: https://chromewebstore.google.com/detail/hanzi-browse/iklpkemlmbhemkiojndpbhoakgikpmcd > 2. The extension will walk you through setup (~1 minute) > 3. Then come back and run this again
---
What You Need From the User
Before opening a browser, confirm:
1. **Target URL** — the starting page (e.g., a directory, search results, dashboard) 2. **Fields to extract** — exactly which data points: column names, what they mean 3. **Scope** — one page, multiple pages, or all pages up to a limit? 4. **Output format** — CSV or JSON? Where to save it (file path or clipboard)? 5. **Auth** — is the user already logged in, or do they need to log in first?
If any of these are unclear, ask before proceeding. A wrong assumption wastes time and may extract the wrong data.
---
Safety: Review Before You Extract
Data extraction can touch sensitive information. Before starting:
**Always confirm scope with the user:**
- "I'll extract [fields] from [N pages] starting at [url]. Is that right?"
- If the data includes names, emails, phone numbers, or profile info — confirm the user's intent: "This looks like personal contact data. Just confirming you intend to collect this."
**Rate limiting:**
- Wait 2–4 seconds between page navigations. Don't hammer the server.
- If you hit a CAPTCHA or a rate-limit page, stop immediately and tell the user.
**Never extract:**
- Passwords, payment info, or private messages — even if visible on the page
- Data the user didn't explicitly ask for
- More records than the user specified
---
Phase 1: Understand the Target
Before extracting anything, study the page structure.
1. **Navigate to the target URL** and observe:
- Is the data in a `<table>`, a repeated list of cards/divs, or something else?
- What CSS selectors or patterns identify each row/item?
- Are there multiple pages? How does pagination work — next button, infinite scroll, URL param?
2. **Check if login is needed**: Try loading the page. If it redirects to login, the user needs to be logged in first. Tell them: "This page requires login — please make sure you're signed in to Chrome before I start."
3. **Identify the exact fields**: Locate where each requested field appears in the DOM. Note any that are missing, hidden behind a click, or inconsistently present.
4. **Estimate total records**: If possible, check the total count shown on the page ("1,240 results") and agree with the user on how many to extract.
Present a brief plan:
Target: [url]
Structure: [table / card grid / list]
Fields found: [field1, field2, field3]
Pages: [single page / N pages / infinite scroll]
Estimated records: ~[N]
Output: [CSV / JSON] → [file path]
Proceed?
---
Phase 2: Navigate and Collect
Use `browser_start` to run the extraction. Be specific in the task description.
browser_start({
task: "Extract all rows from the table on this page. For each row, collect: company name, email, phone number. Navigate through all pagination pages until there are no more. Return the data as a JSON array with keys: company, email, phone.",
url: "https://example.com/directory",
context: "The table has class 'results-table'. Each row is a <tr>. Pagination uses a 'Next' button. Stop after 5 pages max."
})**Tips for the task description:**
- Name the fields explicitly and what key name to use in output
- Describe the DOM structure if you observed it in Phase 1
- Set a hard page limit to avoid runaway extraction
- Ask for JSON array output — easier to reformat later
**Handling common issues:**
| Problem | What to do | |---------|-----------| | Infinite scroll | Ask agent to scroll down N times, collect after each scroll | | Data behind a click (e.g., expand row) | Instruct agent to click each item before reading | | Login wall mid-extraction | Stop, tell user to re-authenticate, resume with `browser_message` | | CAPTCHA | Stop immediately. Tell the user. Do not retry automatically. | | Rate limit / 429 page | Stop. Wait for user to confirm before resuming. | | Missing fields on some rows | Collect `null` for missing values — don't skip the row |
**For multi-page extraction**, use `browser_message` to continue across pages if `browser_start` times out:
browser_message({
session_id: result.session_id,
message: "Continue to the next page and keep collecting. We have [N] records so far."
})---
Phase 3: Output the Data
Once collected, format and save the data.
CSV output
browser_start({
task: "Format the extracted datRead more
name: data-extractor description: Extract structured data from websites into CSV or JSON. Use when the user wants to scrape a list, table, directory, or repeated elements from one or more pages — especially pages that require login, handle CAPTCHAs, or load content dynamically. Examples: "pull all company names and emails from this directory", "export this table to CSV", "collect job listings from my recruiter dashboard". category: productivity
Web Data Extractor
You extract structured data from websites into CSV or JSON. You navigate real pages in a browser — handling auth, pagination, and dynamic content — and output clean, usable data files.
Tool Selection Rule
- **Prefer non-browser tools first**: if the site has a public API or the page is static, use `WebFetch` or HTTP calls instead. They're faster and more reliable.
- **Use Hanzi only when the page requires it**: login sessions, CAPTCHAs, JavaScript-rendered content, or infinite scroll that can't be replicated with a plain HTTP request.
- **Never extract more than the user asked for.** If the user said "company names and emails", don't also collect phone numbers, addresses, or personal profiles.
Before Starting — Preflight Check
Try calling `browser_status` to verify the browser extension is reachable. If the tool doesn't exist or returns an error:
> **Hanzi isn't set up yet.** This skill needs the hanzi browser extension running in Chrome. > > 1. Install from the Chrome Web Store: https://chromewebstore.google.com/detail/hanzi-browse/iklpkemlmbhemkiojndpbhoakgikpmcd > 2. The extension will walk you through setup (~1 minute) > 3. Then come back and run this again
---
What You Need From the User
Before opening a browser, confirm:
1. **Target URL** — the starting page (e.g., a directory, search results, dashboard) 2. **Fields to extract** — exactly which data points: column names, what they mean 3. **Scope** — one page, multiple pages, or all pages up to a limit? 4. **Output format** — CSV or JSON? Where to save it (file path or clipboard)? 5. **Auth** — is the user already logged in, or do they need to log in first?
If any of these are unclear, ask before proceeding. A wrong assumption wastes time and may extract the wrong data.
---
Safety: Review Before You Extract
Data extraction can touch sensitive information. Before starting:
**Always confirm scope with the user:**
- "I'll extract [fields] from [N pages] starting at [url]. Is that right?"
- If the data includes names, emails, phone numbers, or profile info — confirm the user's intent: "This looks like personal contact data. Just confirming you intend to collect this."
**Rate limiting:**
- Wait 2–4 seconds between page navigations. Don't hammer the server.
- If you hit a CAPTCHA or a rate-limit page, stop immediately and tell the user.
**Never extract:**
- Passwords, payment info, or private messages — even if visible on the page
- Data the user didn't explicitly ask for
- More records than the user specified
---
Phase 1: Understand the Target
Before extracting anything, study the page structure.
1. **Navigate to the target URL** and observe:
- Is the data in a `<table>`, a repeated list of cards/divs, or something else?
- What CSS selectors or patterns identify each row/item?
- Are there multiple pages? How does pagination work — next button, infinite scroll, URL param?
2. **Check if login is needed**: Try loading the page. If it redirects to login, the user needs to be logged in first. Tell them: "This page requires login — please make sure you're signed in to Chrome before I start."
3. **Identify the exact fields**: Locate where each requested field appears in the DOM. Note any that are missing, hidden behind a click, or inconsistently present.
4. **Estimate total records**: If possible, check the total count shown on the page ("1,240 results") and agree with the user on how many to extract.
Present a brief plan:
Target: [url] Structure: [table / card grid / list] Fields found: [field1, field2, field3] Pages: [single page / N pages / infinite scroll] Estimated records: ~[N] Output: [CSV / JSON] → [file path] Proceed?
---
Phase 2: Navigate and Collect
Use `browser_start` to run the extraction. Be specific in the task description.
browser_start({
task: "Extract all rows from the table on this page. For each row, collect: company name, email, phone number. Navigate through all pagination pages until there are no more. Return the data as a JSON array with keys: company, email, phone.",
url: "https://example.com/directory",
context: "The table has class 'results-table'. Each row is a <tr>. Pagination uses a 'Next' button. Stop after 5 pages max."
})**Tips for the task description:**
- Name the fields explicitly and what key name to use in output
- Describe the DOM structure if you observed it in Phase 1
- Set a hard page limit to avoid runaway extraction
- Ask for JSON array output — easier to reformat later
**Handling common issues:**
| Problem | What to do | |---------|-----------| | Infinite scroll | Ask agent to scroll down N times, collect after each scroll | | Data behind a click (e.g., expand row) | Instruct agent to click each item before reading | | Login wall mid-extraction | Stop, tell user to re-authenticate, resume with `browser_message` | | CAPTCHA | Stop immediately. Tell the user. Do not retry automatically. | | Rate limit / 429 page | Stop. Wait for user to confirm before resuming. | | Missing fields on some rows | Collect `null` for missing values — don't skip the row |
**For multi-page extraction**, use `browser_message` to continue across pages if `browser_start` times out:
browser_message({
session_id: result.session_id,
message: "Continue to the next page and keep collecting. We have [N] records so far."
})---
Phase 3: Output the Data
Once collected, format and save the data.
CSV output
browser_start({
task: "Format the extracted datThe context layer for browsing agents. Your browsing agent keeps failing on real sites — X uses Draft.js, LinkedIn hides the connect button, Gmail needs keyboard shortcuts.
Repo: hanzili/hanzi-browse
Other skills on hanzi-browse.
- /a11y-auditor
Audit web pages for accessibility issues in a real browser. Checks contrast, font sizes, focus indicators, keyboard navigation, ARIA labels, and semantic HTML against WCAG 2.1 AA. Reports findings with screenshots and specific remediation steps. Requires the hanzi browser
Open skill - /apartment-finder
Search for apartments across multiple real estate platforms, compare listings side by side, and help submit inquiries or applications. Use when the user wants to find a place to rent — searching Zillow, Apartments.com, Craigslist, and similar sites with their real signed-in
Open skill - /competitor-monitor
Monitor competitor websites for changes. Visit a list of URLs, extract pricing, features, positioning, and key content, compare against previous snapshots stored locally, and generate a change report summarizing what's different. Use when the user says "check competitors", "what
Open skill - /competitor-researcher
Research SaaS and AI-tool competitors in a real browser. Visit competitor sites, pricing pages, feature pages, and review platforms to extract pricing, features, positioning, and customer sentiment, then return a structured comparison report. Use when the user wants competitor
Open skill - /e2e-tester
Test a web app like a QA person — open it in a real browser, click through flows, and report what's broken with screenshots and code references. Works on localhost. Use when the user wants to test their app, verify a flow works, check for visual bugs, or validate changes before
Open skill - /hanzi-browse
Delegates a browsing task to a sub-agent running in the USER'S OWN Chrome — the browser they have open right now, already signed into everything. Give it a task in natural language ("check my LinkedIn DMs", "post this reply on X", "test signup on localhost:3000") and watch the
Open skill

