Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add pencil20388-eng/browser-automation-skills --skill web-scrapinggit clone --depth 1 https://github.com/pencil20388-eng/browser-automation-skillsWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/pencil20388-eng/browser-automation-skills/web-scraping)<a href="https://agentmods.dev/skills/pencil20388-eng/browser-automation-skills/web-scraping"><img src="https://agentmods.dev/badge/skills/pencil20388-eng/browser-automation-skills/web-scraping/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/pencil20388-eng/browser-automation-skills/web-scraping"><img src="https://agentmods.dev/badge/skills/pencil20388-eng/browser-automation-skills/web-scraping.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00000 | $0.01095 |
| Opus 5.5 | $0.00000 | $0.00438 |
| Sonnet 5.5 | $0.00000 | $0.00219 |
| Haiku 4.5 | $0.00000 | $0.00110 |
Grade A, and why
web-scraping scanned grade A with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2mo ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Makes network callslowCapability
Not a fault in itself. Listed so you know the mod talks to something, and to what.
resp = requests.get("https://example.com", timeout=10) How it starts
The opening of the file, as written. The whole thing — 160 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Web Scraping Skill
Extract structured data from websites. Covers static scraping (fast, lightweight) and dynamic scraping (for JavaScript-rendered pages).
When to use what
| Approach | When to use | Speed | Libraries |
|---|---|---|---|
| Static (requests + BS4) | Server-rendered HTML, APIs | Fast | requests, beautifulsoup4, lxml |
| Dynamic (browser) | JavaScript-rendered, SPAs | Slower | playwright, selenium |
Default to static scraping. Only use browser-based scraping if the content is rendered by JavaScript.
Installation
# Static scraping
pip install requests beautifulsoup4 lxml
# Dynamic scraping (if needed)
pip install playwright && playwright install chromium
Static Scraping Patterns
Basic page fetch + parse
import requests
from bs4 import BeautifulSoup
resp = requests.get("https://example.com", timeout=10)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "lxml")
title = soup.find("h1").text
links = [a["href"] for a in soup.select("a[href]")]
Extract structured data
products = []
for card in soup.select(".product-card"):
products.append({
"name": card.select_one(".name").text.strip(),
"price": card.select_one(".price").text.strip(),
"url": card.select_one("a")["href"],
})
Handle pagination
all_items = []
page = 1
while True:
resp = requests.get(f"https://example.com/products?page={page}", timeout=10)
soup = BeautifulSoup(resp.text, "lxml")
items = soup.select(".product-card")
if not items:
break # No more pages
for item in items:
all_items.append(item.select_one(".name").text.strip())
page += 1
time.sleep(1) # Be polite
print(f"Scraped {len(all_items)} items across {page - 1} pages")
Set headers to avoid blocks
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
}
resp = requests.get(url, headers=headers, timeout=10)
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2mo ago First seen · 160 lines · 0 tokens per session scan A 339d67fa5015
web-scraping is a skill published in the GitHub repository pencil20388-eng/browser-automation-skills (5 stars, last pushed 5mo ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 1,095 tokens. A static security scan graded it A with 1 finding (makes network calls). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
web-scraping compared with skills from other repositories
| Mod | Type | Stars | Last push | Licence | Scan | Tokens | Works with |
|---|---|---|---|---|---|---|---|
| web-scrapingpencil20388-eng/browser-automation-skills | Skill | 5 | 5mo ago | MIT | A | 0 | Claude Code, Codex |
| mk:playwright-clingocsangyem/MeowKit | Skill | 15 | 5d ago | MIT | A | 92 | Claude Code |
| screenshot-urltoolshedlabs-hash/web-access-skills | Skill | 0 | 3mo ago | MIT | A | 159 | Claude Code, Codex |
| url-to-markdowntoolshedlabs-hash/web-access-skills | Skill | 0 | 3mo ago | MIT | A | 141 | Claude Code, Codex |
| url-to-pdftoolshedlabs-hash/web-access-skills | Skill | 0 | 3mo ago | MIT | A | 138 | Claude Code, Codex |
| postEpistates/sparX | Skill | 4 | 7mo ago | MIT | A | 39 | Claude Code |
| engageEpistates/sparX | Skill | 4 | 7mo ago | MIT | A | 50 | Claude Code |