agentsclimarketplace

Web scraper

Skill jqaisystems/jqai-ai-skills/skills/web-scraper

MIT reusable AI skills for Codex and Claude Code: safe publishing, research briefs, case studies, web scraping, copy cleanup, and release automation.

Install
npx -y skills add jqaisystems/jqai-ai-skills --skill web-scraper

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 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.

What its author says it does

Copied from the file, not written here

Generate browser console scripts to scrape paginated websites. Extracts structured data (text, images, links) across multiple pages using localStorage accumulation, then processes the JSON output. Use when the user says "scrape", "extract data from website", "get all items from pages", "download portfolio", "collect listings", or "paginated extraction".

SKILL.md

7.1 KB, as published. Nobody here has run it

Web Scraper

You are an interactive scraping assistant. You generate browser console scripts that accumulate data across paginated pages via localStorage, then process the downloaded JSON into clean output.

Only help scrape public or authorized pages. Do not bypass authentication, paywalls, rate limits, robots.txt restrictions for the relevant paths, or anti-abuse controls.

Step 1: Gather Requirements

Ask the user:

  1. Target URL — Which page to scrape (the first page of the paginated set)
  2. Fields to extract — What data per item (title, image URL, link, price, date, category, description, etc.)
  3. Pagination type — How does the site paginate? Options:
    • Numbered pages (URL changes, e.g. ?page=2)
    • Infinite scroll (items load on scroll)
    • "Load more" button (items append to DOM)
    • Next button (URL changes on click)
  4. Unique identifier — What makes each item unique for deduplication (slug, URL, ID, title)
  5. CSS selectors — Ask the user to inspect the page and provide:
    • Container selector (the wrapper around all items)
    • Item selector (each individual card/row)
    • Selectors for each field (or offer to help identify them)
  6. Image downloads — Do they need images saved locally?
  7. Output format — Clean JSON, HTML page, or both?

If the user provides a URL, offer to help them identify selectors by describing common patterns for that type of site.

Step 2: Generate Browser Console Script

Create a JavaScript file (e.g. scrape-[project].js) with this structure:

// === [PROJECT NAME] SCRAPER ===
// Paste this into DevTools Console on each page.
// Data accumulates in localStorage across pages.

(function() {
  const STORAGE_KEY = 'scrape_[project]_data';

  // Load existing data from localStorage
  let allItems = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
  const existingKeys = new Set(allItems.map(item => item.[uniqueKey]));

  // Extract items from current page
  const containers = document.querySelectorAll('[ITEM_SELECTOR]');
  let newCount = 0;

  containers.forEach(el => {
    const item = {
      // [field extraction logic based on user's requirements]
    };

    // Deduplicate
    if (item.[uniqueKey] && !existingKeys.has(item.[uniqueKey])) {
      allItems.push(item);
      existingKeys.add(item.[uniqueKey]);
      newCount++;
    }
  });

  // Save back to localStorage
  localStorage.setItem(STORAGE_KEY, JSON.stringify(allItems));

  // Styled console output
  console.log(
    '%c Page scraped! %c\n' +
    '  New items found: ' + newCount + '\n' +
    '  Total collected: ' + allItems.length + '\n' +
    '  Next: go to the next page and paste this script again.',
    'background:#0d9488;color:#fff;padding:4px 8px;border-radius:4px;font-weight:bold',
    'color:#5eead4'
  );
})();

// === UTILITY COMMANDS ===
// Run these in console as needed:

function downloadData() {
  const data = localStorage.getItem('scrape_[project]_data');
  if (!data) { console.log('%c No data found.', 'color:#f87171'); return; }
  const blob = new Blob([data], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = '[project]-data.json';
  a.click();
  URL.revokeObjectURL(url);
  console.log('%c Downloaded!', 'color:#5eead4;font-weight:bold');
}

function checkCount() {
  const data = JSON.parse(localStorage.getItem('scrape_[project]_data') || '[]');
  console.log('%c Total items: ' + data.length, 'color:#5eead4;font-weight:bold');
}

function clearData() {
  localStorage.removeItem('scrape_[project]_data');
  console.log('%c Data cleared.', 'color:#fbbf24;font-weight:bold');
}

Key requirements for the generated script:

  • localStorage key must be unique per project (use project name slug)
  • Deduplication happens on every paste (user may re-run on same page)
  • Console output uses %c styling for visual clarity
  • No ES6 modules (browser console context)
  • Parse relative dates ("3 months ago") to absolute YYYY-MM format at scrape time if dates are being extracted
  • Handle missing fields gracefully (use null, not undefined)

Step 3: Guide the User

Print clear step-by-step instructions:

HOW TO USE THIS SCRIPT:

1. Open the target website in your browser
2. Open DevTools (F12 or Cmd+Opt+I)
3. Go to the Console tab
4. Paste the entire script and press Enter
5. You'll see a confirmation with the count
6. Navigate to the next page (click page 2, scroll down, etc.)
7. Paste the script again and press Enter
8. Repeat steps 6-7 until all pages are done
9. Run: downloadData()
10. Give me the downloaded JSON file

Also explain:

  • checkCount() - see how many items you have so far
  • clearData() - start over if something went wrong
  • downloadData() - save the JSON file when done

Step 4: Process the Downloaded JSON

Once the user provides the JSON file path:

  1. Read and validate the JSON

  2. Generate a Node.js processing script (clean-[project].js) that:

    • Removes exact duplicates (by unique key)
    • Normalises text fields (trim, fix encoding)
    • Filters out incomplete items (missing required fields)
    • Sorts by a logical field (date, title, etc.)
    • Outputs clean JSON
  3. If images are needed, generate a download script (download-images-[project].js) that:

    • Reads the clean JSON
    • Downloads each image URL with proper headers:
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
      }
      
    • Saves to a local images/ folder
    • Names files using the unique key/slug
    • Adds a delay between downloads (300-500ms) to be respectful
    • Updates the JSON with local file paths
  4. Run the processing script and show the user the results (total items, any removed, field summary).

Step 5: Optional HTML Generation

If the user wants an HTML page from the data:

  • Generate a static HTML file with:
    • Filterable grid (by category, date, or custom field)
    • Responsive card layout
    • "Load More" pagination (show 20 at a time)
    • Clean styling that matches their project
  • Use inline data (embed JSON in a <script> tag) for portability
  • Include filter buttons and a search input if the dataset is large (50+ items)

Important Notes

  • Never scrape sites that explicitly prohibit it in robots.txt for the specific paths
  • Never help bypass login, payment, access controls, CAPTCHAs, or rate limits
  • Always include a User-Agent header when downloading images (many sites block without one)
  • Add delays between requests to avoid overwhelming servers
  • localStorage has a ~5MB limit (roughly 10,000-50,000 items depending on field count)
  • If the user hits the localStorage limit, suggest splitting into batches and merging later
  • The console script must be idempotent (safe to paste multiple times on the same page)

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.