Web scraper
Extracts structured data from websites, handling pagination, JavaScript rendering, and rate limiting. Invoke when asked to scrape a website, extract data from web pages, crawl URLs, harvest structured content, or automate web data collection.From its SKILL.md
npx -y skills add VRIL-LABS/skill-jam --skill web-scraperAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.6 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Web Scraper
Extracts structured data from any website — handling static HTML, JavaScript-rendered pages, pagination, authentication walls, and rate limiting — and returns clean, structured output ready for downstream processing.
When to Use
- User wants to extract product listings, prices, or reviews from an e-commerce site
- User needs to harvest article text, metadata, or links from a news or blog site
- A dataset must be built by collecting structured records across many pages
- User asks to "scrape", "crawl", "extract data from", or "harvest" a URL
- An automated pipeline needs to pull live data from a website on a schedule
- User needs to monitor a page for changes and capture diffs over time
Process
-
Analyze the target URL and content type:
- Determine whether the page is static HTML or JavaScript-rendered (check for
<script>tags that load content dynamically) - Identify the data schema: what fields are needed and where do they appear in the DOM?
- Check for a
robots.txtand note any disallowed paths or crawl delays
- Determine whether the page is static HTML or JavaScript-rendered (check for
-
Select the extraction strategy:
- Static HTML: Use
requests+BeautifulSoup(Python) orcheerio(Node.js) - JavaScript-rendered: Use
PlaywrightorPuppeteerto render the page before parsing - APIs hiding behind the UI: Inspect network traffic (XHR/fetch calls) — hitting the API directly is faster and more reliable
- Structured data already present: Check for JSON-LD (
<script type="application/ld+json">), Open Graph tags, or schema.org microdata
- Static HTML: Use
-
Handle pagination and navigation:
- Detect pagination pattern: URL query parameter (
?page=2), path segment (/page/2), infinite scroll, or "Load More" button - For query-parameter pagination: iterate pages until response is empty or a sentinel value is reached
- For infinite scroll: scroll the viewport incrementally with Playwright, waiting for new content to load
- Detect pagination pattern: URL query parameter (
-
Implement rate limiting and politeness:
- Respect
Crawl-delayfromrobots.txt; default to 1–2 seconds between requests if none specified - Randomize delay within ±50% of the target to avoid fingerprinting
- Use rotating user-agent strings drawn from a realistic pool
- Back off exponentially on 429 or 503 responses (2s → 4s → 8s → give up after 3 retries)
- Respect
-
Extract and normalize fields:
- Use CSS selectors or XPath to target each field precisely
- Strip HTML entities, extra whitespace, and boilerplate text
- Normalize dates to ISO 8601, prices to a
{amount, currency}object, and URLs to absolute form
-
Handle errors and gaps:
- Log missing fields per record rather than dropping the entire record
- Detect CAPTCHAs or login walls and surface them as explicit errors with remediation advice
- Validate extracted records against the expected schema before returning
-
Return structured output:
- Default format: JSON array of objects (one per scraped record)
- Include scrape metadata:
source_url,scraped_at(ISO 8601),page_count,record_count
Output Format
{
"metadata": {
"source_url": "https://example.com/products",
"scraped_at": "2025-06-01T14:32:00Z",
"page_count": 5,
"record_count": 120
},
"records": [
{
"title": "Wireless Headphones Pro",
"price": { "amount": 79.99, "currency": "USD" },
"rating": 4.5,
"review_count": 312,
"url": "https://example.com/products/wireless-headphones-pro"
}
]
}
Examples
Example Input
Scrape all product names and prices from https://books.toscrape.com — there are multiple pages.
Example Output
import requests
from bs4 import BeautifulSoup
import time, random, json
from datetime import datetime, timezone
BASE_URL = "https://books.toscrape.com/catalogue/"
records = []
page = 1
while True:
url = f"{BASE_URL}page-{page}.html" if page > 1 else "https://books.toscrape.com/catalogue/"
resp = requests.get(url, headers={"User-Agent": "Mozilla/5.0"})
if resp.status_code == 404:
break
soup = BeautifulSoup(resp.text, "html.parser")
for article in soup.select("article.product_pod"):
records.append({
"title": article.h3.a["title"],
"price": article.select_one(".price_color").text.strip(),
"url": "https://books.toscrape.com/catalogue/" + article.h3.a["href"]
})
page += 1
time.sleep(random.uniform(0.8, 1.5))
print(json.dumps({
"metadata": {"scraped_at": datetime.now(timezone.utc).isoformat(), "record_count": len(records)},
"records": records
}, indent=2))
Boundaries
- Always check
robots.txtbefore scraping and respectDisallowrules andCrawl-delay. - Do NOT bypass authentication mechanisms or scrape content behind a login without explicit user confirmation that they are authorized to do so.
- Do NOT extract personally identifiable information (PII) unless the user explicitly needs it and confirms they have legal authority to collect it.
- Do NOT ignore HTTP 429/503 responses — always back off before retrying.
- Do NOT scrape at rates that could constitute a denial-of-service — cap at one request per second by default.
- Flag CAPTCHA walls as an explicit blocker; do NOT attempt to solve CAPTCHAs automatically.
- Remind users that scraping may violate a site's Terms of Service — this is their responsibility to verify.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.