Extract webpage data

Extract structured data from web pages using AI

How to use it

  1. Hit Copy the whole skill.
  2. Claude: ⋯ → Download .md, then Customize → Skills → Add → Upload skill.
    ChatGPT: make a Project and paste it into Instructions.
    Neither? Paste it at the top of a new chat — it works for that chat.
  3. Describe your job in plain words. The AI follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit gooseworks-ai/goose-skills/skills/research-tools/capabilities/extract-webpage-data#main ~/.claude/skills/extract-webpage-data

For one project only, change the path to .claude/skills/extract-webpage-data.

Not working?
  • Check which app you pasted it into — the steps above name the right one.
  • Some skills need the paid tier of Claude or ChatGPT.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Show the full text188 lines
extract-webpage-data/SKILL.md188 lines7.3 KBpushed 96d agoRawView on GitHub

Extract Webpage Data

Setup

Read your credentials from ~/.gooseworks/credentials.json:

export GOOSEWORKS_API_KEY=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json'))['api_key'])")
export GOOSEWORKS_API_BASE=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json')).get('api_base','https://api.gooseworks.ai'))")

If ~/.gooseworks/credentials.json does not exist, tell the user to run: npx gooseworks login

All endpoints use Bearer auth: -H "Authorization: Bearer $GOOSEWORKS_API_KEY"

Extract structured data from any web page using AI. Turn messy HTML into clean, organized data.

When to Use

  • User wants to extract specific data from a website
  • User asks to scrape information from a page
  • User needs structured data from unstructured content
  • User wants to pull product info, contact details, etc.
  • Converting web content to usable data

How It Works

Uses Olostep, Scrapegraph, or Riveter APIs for AI-powered data extraction.

Usage

Simple Scrape with Olostep

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"olostep","path":"/v1/scrapes","body":{"url_to_scrape":"https://example.com/products"}}'

AI-Powered Extraction with Scrapegraph

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"scrapegraph","path":"/v1/smartscraper","body":{"website_url":"https://example.com/team","user_prompt":"Extract all team members with their names, titles, and LinkedIn URLs"}}'

Schema-Based Extraction with Riveter

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"riveter","path":"/v1/scrape","body":{"url":"https://example.com","schema":{"name":"string","price":"number","description":"string"}}}'

Get AI Answer from Web

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"olostep","path":"/v1/answers","body":{"task":"Find the pricing for Notion Teams plan from their website"}}'

Crawl Multiple Pages

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"olostep","path":"/v1/crawls","body":{"start_url":"https://example.com","max_pages":10}}'

Parameters

Olostep Scrape

  • url_to_scrape (required) - URL to scrape
  • formats - Output formats (markdown, html, text)

Scrapegraph

  • website_url (required) - URL to scrape
  • user_prompt (required) - Natural language description of what to extract

Riveter

  • url (required) - URL to scrape
  • schema - JSON schema defining the data structure to extract

Olostep Answer

  • task (required) - Natural language task/question

Response

Olostep Response

Returns a scrape object:

  • id (string) - Scrape ID (e.g., scrape_z926lxxon3)
  • result.markdown_content (string|null) - Page content as markdown
  • result.html_content (string|null) - Raw HTML (if requested via formats)
  • result.text_content (string|null) - Plain text (if requested)
  • result.markdown_hosted_url (string|null) - S3 URL for large content
  • result.links_on_page (array) - Links found on the page
  • result.screenshot_hosted_url (string|null) - Screenshot URL (if requested)
  • result.page_metadata (object) - status_code of the page
  • credits_consumed (integer) - Credits used for this scrape

Async crawls: POST /v1/crawls returns an id. Poll with GET /v1/crawls/{id} until complete.

Scrapegraph Response

Returns structured extraction result:

  • request_id (string) - Unique request identifier
  • status (string) - completed or pending
  • result (object) - AI-extracted data matching your prompt (dynamic keys)
  • error (string) - Empty on success, error message on failure

Note: For large pages, the POST may return status: "pending". Poll with GET /v1/smartscraper/{request_id} until status is completed.

Riveter Response

Returns scrape result:

  • request_status (string) - success or error
  • message (string) - Human-readable status
  • text (string) - Extracted page text content
  • url (string) - URL that was scraped
  • status_code (integer) - HTTP status of the page
  • run_key (string) - Unique run identifier
  • base_url_for_links (string) - Base URL for resolving relative links
  • riveter_app_link (string) - Link to view run in Riveter dashboard
  • credit_used (integer) - Credits consumed

Examples

User: "Get all the product names and prices from this page"

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"scrapegraph","path":"/v1/smartscraper","body":{"website_url":"https://example.com/products","user_prompt":"Extract all products with name, price, and description"}}'

User: "Scrape the team page and get everyone's info"

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"scrapegraph","path":"/v1/smartscraper","body":{"website_url":"https://example.com/about/team","user_prompt":"Extract team members: name, role, bio, photo URL, LinkedIn"}}'

User: "What are Stripe's API pricing details?"

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"olostep","path":"/v1/answers","body":{"task":"Find Stripe API pricing breakdown from stripe.com/pricing"}}'

User: "Get all blog post titles and dates from this blog"

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"riveter","path":"/v1/scrape","body":{"url":"https://blog.example.com","schema":{"posts":[{"title":"string","date":"string","url":"string"}]}}}'

Error Handling

  • 504 - Olostep timeout on slow pages — retry or try a simpler URL
  • 400 - Missing required parameters (url_to_scrape for Olostep, website_url + user_prompt for Scrapegraph, url for Riveter)
  • Scrapegraph returns error field in response body — check it even on 200 status
  • Riveter returns request_status: "error" with details in message
  • Some sites block automated scraping — try a different API if one fails

Tips

  • Scrapegraph is best for natural language extraction
  • Riveter is best when you know the exact schema you want
  • Olostep is great for general scraping and AI answers
  • For dynamic sites (JavaScript-heavy), these tools handle rendering
  • Be specific in your prompts for better extraction results
  • Some sites may block automated access
1---
2name: extract-webpage-data
3description: Extract structured data from web pages using AI
4source: orthogonal
5---
6 
7 
8# Extract Webpage Data
9 
10## Setup
11 
12Read your credentials from ~/.gooseworks/credentials.json:
13```bash
14export GOOSEWORKS_API_KEY=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json'))['api_key'])")
15export GOOSEWORKS_API_BASE=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json')).get('api_base','https://api.gooseworks.ai'))")
16```
17 
18If ~/.gooseworks/credentials.json does not exist, tell the user to run: `npx gooseworks login`
19 
20All endpoints use Bearer auth: `-H "Authorization: Bearer $GOOSEWORKS_API_KEY"`
21 
22 
23Extract structured data from any web page using AI. Turn messy HTML into clean, organized data.
24 
25## When to Use
26 
27- User wants to extract specific data from a website
28- User asks to scrape information from a page
29- User needs structured data from unstructured content
30- User wants to pull product info, contact details, etc.
31- Converting web content to usable data
32 
33## How It Works
34 
35Uses Olostep, Scrapegraph, or Riveter APIs for AI-powered data extraction.
36 
37## Usage
38 
39### Simple Scrape with Olostep
40 
41```bash
42curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
43 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
44 -H "Content-Type: application/json" \
45 -d '{"api":"olostep","path":"/v1/scrapes","body":{"url_to_scrape":"https://example.com/products"}}'
46```
47 
48### AI-Powered Extraction with Scrapegraph
49 
50```bash
51curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
52 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
53 -H "Content-Type: application/json" \
54 -d '{"api":"scrapegraph","path":"/v1/smartscraper","body":{"website_url":"https://example.com/team","user_prompt":"Extract all team members with their names, titles, and LinkedIn URLs"}}'
55```
56 
57### Schema-Based Extraction with Riveter
58 
59```bash
60curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
61 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
62 -H "Content-Type: application/json" \
63 -d '{"api":"riveter","path":"/v1/scrape","body":{"url":"https://example.com","schema":{"name":"string","price":"number","description":"string"}}}'
64```
65 
66### Get AI Answer from Web
67 
68```bash
69curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
70 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
71 -H "Content-Type: application/json" \
72 -d '{"api":"olostep","path":"/v1/answers","body":{"task":"Find the pricing for Notion Teams plan from their website"}}'
73```
74 
75### Crawl Multiple Pages
76 
77```bash
78curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
79 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
80 -H "Content-Type: application/json" \
81 -d '{"api":"olostep","path":"/v1/crawls","body":{"start_url":"https://example.com","max_pages":10}}'
82```
83 
84## Parameters
85 
86### Olostep Scrape
87- **url_to_scrape** (required) - URL to scrape
88- **formats** - Output formats (markdown, html, text)
89 
90### Scrapegraph
91- **website_url** (required) - URL to scrape
92- **user_prompt** (required) - Natural language description of what to extract
93 
94### Riveter
95- **url** (required) - URL to scrape
96- **schema** - JSON schema defining the data structure to extract
97 
98### Olostep Answer
99- **task** (required) - Natural language task/question
100 
101## Response
102 
103### Olostep Response
104Returns a scrape object:
105- **id** (string) - Scrape ID (e.g., `scrape_z926lxxon3`)
106- **result.markdown_content** (string|null) - Page content as markdown
107- **result.html_content** (string|null) - Raw HTML (if requested via `formats`)
108- **result.text_content** (string|null) - Plain text (if requested)
109- **result.markdown_hosted_url** (string|null) - S3 URL for large content
110- **result.links_on_page** (array) - Links found on the page
111- **result.screenshot_hosted_url** (string|null) - Screenshot URL (if requested)
112- **result.page_metadata** (object) - `status_code` of the page
113- **credits_consumed** (integer) - Credits used for this scrape
114 
115**Async crawls**: POST `/v1/crawls` returns an `id`. Poll with GET `/v1/crawls/{id}` until complete.
116 
117### Scrapegraph Response
118Returns structured extraction result:
119- **request_id** (string) - Unique request identifier
120- **status** (string) - `completed` or `pending`
121- **result** (object) - AI-extracted data matching your prompt (dynamic keys)
122- **error** (string) - Empty on success, error message on failure
123 
124**Note**: For large pages, the POST may return `status: "pending"`. Poll with GET `/v1/smartscraper/{request_id}` until `status` is `completed`.
125 
126### Riveter Response
127Returns scrape result:
128- **request_status** (string) - `success` or `error`
129- **message** (string) - Human-readable status
130- **text** (string) - Extracted page text content
131- **url** (string) - URL that was scraped
132- **status_code** (integer) - HTTP status of the page
133- **run_key** (string) - Unique run identifier
134- **base_url_for_links** (string) - Base URL for resolving relative links
135- **riveter_app_link** (string) - Link to view run in Riveter dashboard
136- **credit_used** (integer) - Credits consumed
137 
138## Examples
139 
140**User:** "Get all the product names and prices from this page"
141```bash
142curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
143 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
144 -H "Content-Type: application/json" \
145 -d '{"api":"scrapegraph","path":"/v1/smartscraper","body":{"website_url":"https://example.com/products","user_prompt":"Extract all products with name, price, and description"}}'
146```
147 
148**User:** "Scrape the team page and get everyone's info"
149```bash
150curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
151 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
152 -H "Content-Type: application/json" \
153 -d '{"api":"scrapegraph","path":"/v1/smartscraper","body":{"website_url":"https://example.com/about/team","user_prompt":"Extract team members: name, role, bio, photo URL, LinkedIn"}}'
154```
155 
156**User:** "What are Stripe's API pricing details?"
157```bash
158curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
159 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
160 -H "Content-Type: application/json" \
161 -d '{"api":"olostep","path":"/v1/answers","body":{"task":"Find Stripe API pricing breakdown from stripe.com/pricing"}}'
162```
163 
164**User:** "Get all blog post titles and dates from this blog"
165```bash
166curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
167 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
168 -H "Content-Type: application/json" \
169 -d '{"api":"riveter","path":"/v1/scrape","body":{"url":"https://blog.example.com","schema":{"posts":[{"title":"string","date":"string","url":"string"}]}}}'
170```
171 
172## Error Handling
173 
174- **504** - Olostep timeout on slow pages — retry or try a simpler URL
175- **400** - Missing required parameters (`url_to_scrape` for Olostep, `website_url` + `user_prompt` for Scrapegraph, `url` for Riveter)
176- Scrapegraph returns `error` field in response body — check it even on 200 status
177- Riveter returns `request_status: "error"` with details in `message`
178- Some sites block automated scraping — try a different API if one fails
179 
180## Tips
181 
182- Scrapegraph is best for natural language extraction
183- Riveter is best when you know the exact schema you want
184- Olostep is great for general scraping and AI answers
185- For dynamic sites (JavaScript-heavy), these tools handle rendering
186- Be specific in your prompts for better extraction results
187- Some sites may block automated access
188 

Discussion

Alternatives

Also in Scraping & extraction