Install
$ agentstack add skill-jignesh-ponamwar-skills-mcp-web-scraper ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Web Scraper Skill
Overview
Extract structured data from websites responsibly. Choose the right tool based on whether the page is static HTML or requires JavaScript execution, then handle pagination, rate limiting, and data cleaning.
Tool Selection
| Situation | Tool | |-----------|------| | Static HTML, simple pages | requests + beautifulsoup4 | | JS-rendered content (SPAs, React/Vue) | playwright or selenium | | Heavy scraping / crawling | scrapy | | API available | Use the API - always prefer it |
Step-by-Step Process
Step 1: Check for an API First
Before scraping, check:
robots.txtatsite.com/robots.txt- The site's developer docs for a public API
- Network tab in DevTools - many "scraped" sites already have an XHR/fetch API
If an API exists, use it. It's faster, more reliable, and respectful.
Step 2: Static HTML Scraping
import requests
from bs4 import BeautifulSoup
import time
headers = {
"User-Agent": "Mozilla/5.0 (compatible; research-bot/1.0; +https://example.com/bot)"
}
response = requests.get("https://example.com/products", headers=headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
# Find elements by CSS selector
items = soup.select("div.product-card")
for item in items:
name = item.select_one("h2.product-name").get_text(strip=True)
price = item.select_one("span.price").get_text(strip=True)
link = item.select_one("a")["href"]
print(name, price, link)
Step 3: JavaScript-Rendered Pages
from playwright.sync_api import sync_playwright
import time
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://example.com/spa-page", wait_until="networkidle")
# Wait for dynamic content
page.wait_for_selector("div.results")
# Extract data
items = page.query_selector_all("div.product-card")
for item in items:
name = item.query_selector("h2").inner_text()
price = item.query_selector("span.price").inner_text()
print(name, price)
browser.close()
Step 4: Handle Pagination
import requests
from bs4 import BeautifulSoup
results = []
page = 1
while True:
url = f"https://example.com/listings?page={page}"
response = requests.get(url, headers=headers, timeout=10)
soup = BeautifulSoup(response.text, "html.parser")
items = soup.select("div.item")
if not items:
break # No more results
for item in items:
results.append(item.get_text(strip=True))
next_btn = soup.select_one("a.next-page")
if not next_btn:
break
page += 1
time.sleep(1.5) # Respectful delay between requests
Step 5: Save and Clean the Data
import pandas as pd
import re
df = pd.DataFrame(results)
# Clean price strings
df["price"] = df["price"].str.replace(r"[^\d.]", "", regex=True).astype(float)
# Normalize URLs
df["url"] = df["url"].apply(lambda u: u if u.startswith("http") else f"https://example.com{u}")
df.to_csv("scraped_data.csv", index=False)
Rate Limiting and Politeness
- Always add delays:
time.sleep(1)minimum between requests - Respect
Crawl-delayinrobots.txt - Set a descriptive
User-Agentwith contact info - Don't send more than 1 request/second without explicit permission
Anti-bot Countermeasures
- 429 Too Many Requests: back off exponentially, add jitter
- Cloudflare / bot detection: use
playwrightwith a real browser profile; avoid headless detection signatures - IP blocks: rotate residential proxies if permitted by the site's ToS
- CAPTCHAs: do not attempt to bypass - respect the site's access controls
Legal and Ethical Notes
- Only scrape publicly accessible data
- Don't scrape personal data (names, emails, phone numbers) without a legal basis
- Check the site's Terms of Service before scraping at scale
- Don't store or republish copyrighted content
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Jignesh-Ponamwar
- Source: Jignesh-Ponamwar/skills-mcp
- License: Apache-2.0
- Homepage: https://skills-mcp-jignesh.vercel.app/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.