web-crawling
Skill1 starsChanged 7 months agoMITView on GitHub
Use when scraping web pages, automating browser interactions, crawling sites for content, or extracting data from rendered JavaScript pages
2 other projects use a version of this.
Adopted by
Most recently taken up by
- mahumadad/quarrytheir own version, first seen Nov 8, 2026
- valtterimelkko/agent-workflow-skillstheir own version, first seen Sep 30, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- valtterimelkko/agent-workflow-skills★ 2same name
- mahumadad/quarry★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository6 other files it gives its agents.
- api-testingSkill
- ci-automationSkill
- data-processingSkill
- python-toolingSkill
- security-scanningSkill
- web-researchSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 3 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 180
Prefer Playwright over curl for JavaScript-rendered pages — curl only gets raw HTML, Playwright executes JS
- Distinctive: line 181
Prefer Katana over manual URL enumeration — fast, recursive, handles JS links
- Distinctive: line 182
Prefer Scrapy over ad-hoc scripts for structured multi-page crawling — built-in rate limiting, pipelines, persistence
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Web Crawling
When to Use
- Scraping content from web pages (especially JavaScript-rendered)
- Automating browser interactions (login, form submission, navigation)
- Crawling a site to discover and extract structured data
- Taking screenshots or generating PDFs of web pages
- Discovering URLs and endpoints on a target site
- Extracting data from sites with anti-bot protection
Tools
| Tool | Purpose | When to choose |
| Playwright | Cross-browser automation (Chromium, Firefox, WebKit) | JS-rendered pages, screenshots, complex interactions |
| Puppeteer | Chrome/Firefox automation via DevTools Protocol | Chrome-specific automation, familiar API |
| Scrapy | Production-grade Python crawling framework | Large-scale structured crawling with pipelines |
| Crawlee | Node.js crawling with anti-blocking built in | Sites with bot detection, proxy rotation needed |
| Katana | Fast Go-based URL discovery crawler | Endpoint discovery, reconnaissance, speed |
Patterns
Playwright: Scrape a page (inline Node.js script)
node -e "
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
const title = await page.title();
const text = await page.locator('body').innerText();
console.log(JSON.stringify({ title, text }));
await browser.close();
})();
"Playwright: Take a screenshot
node -e "
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'screenshot.png', fullPage: true });
await browser.close();
})();
"Playwright: Extract structured data from a table
node -e "
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com/data');
const rows = await page.locator('table tr').evaluateAll(trs =>
trs.map(tr => Array.from(tr.querySelectorAll('td,th')).map(c => c.textContent.trim()))
);
console.log(JSON.stringify(rows));
await browser.close();
})();
"Playwright: Wait for JS content to load
node -e "
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com/spa');
await page.waitForSelector('.content-loaded');
const data = await page.locator('.content-loaded').innerText();
console.log(data);
await browser.close();
})();
"Puppeteer: Generate PDF from a page
node -e "
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
await page.pdf({ path: 'output.pdf', format: 'A4' });
await browser.close();
})();
"Katana: Discover all URLs on a site
katana -u https://example.com -silent -d 3Katana: Discover URLs and output as JSON
katana -u https://example.com -silent -d 2 -jsonlKatana: Crawl with headless browser for JS-rendered links
katana -u https://example.com -headless -d 2 -silentScrapy: Quick single-page scrape (no project needed)
scrapy fetch --nolog https://example.com | python3 -c "
import sys
from scrapy import Selector
html = sys.stdin.read()
sel = Selector(text=html)
for item in sel.css('h2::text').getall():
print(item)
"Crawlee: Basic crawler with anti-blocking
node -e "
const { PlaywrightCrawler } = require('crawlee');
const crawler = new PlaywrightCrawler({
async requestHandler({ page, request }) {
const title = await page.title();
console.log(JSON.stringify({ url: request.url, title }));
},
maxRequestsPerCrawl: 10,
});
crawler.run(['https://example.com']);
"Pipelines
Discover URLs → filter interesting ones → scrape
katana -u https://example.com -silent -d 2 | grep '/blog/' | head -5 | while read url; do
node -e "
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('$url');
const title = await page.title();
const text = await page.locator('article').innerText().catch(() => '');
console.log(JSON.stringify({ url: '$url', title, text: text.slice(0, 500) }));
await browser.close();
})();
"
doneEach stage: Katana discovers URLs, grep filters to blog posts, Playwright scrapes each page.
Crawl → extract to JSON → query with DuckDB
katana -u https://example.com -silent -d 2 -jsonl > crawl.jsonl
duckdb -c "SELECT endpoint, status_code, COUNT(*) FROM read_json_auto('crawl.jsonl') GROUP BY endpoint, status_code ORDER BY COUNT(*) DESC"Each stage: Katana crawls to JSONL, DuckDB runs SQL on the crawl results.
Prefer Over
- Prefer Playwright over curl for JavaScript-rendered pages — curl only gets raw HTML, Playwright executes JS
- Prefer Katana over manual URL enumeration — fast, recursive, handles JS links
- Prefer Scrapy over ad-hoc scripts for structured multi-page crawling — built-in rate limiting, pipelines, persistence
Do NOT Use When
- Page content is available via a REST API — use the API directly (api-testing skill)
- Extracting article text from a news URL — use newspaper4k (web-research skill), it's purpose-built
- Simple static HTML that curl can fetch — use
curl+jq/pup - The site explicitly prohibits scraping — respect robots.txt and ToS
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

