Prompt

How can I scrape data from multiple websites at once?

Latest observation

Jul 15, 2026 · OpenAI APIWeb search: off

You can scrape multiple websites at once by running multiple requests concurrently and keeping each site’s parsing logic separate. The main ideas are:

1) Pick the right approach

  • Simple pages: use requests + BeautifulSoup
  • JavaScript-heavy sites: use Playwright or Selenium
  • Large-scale / many URLs: use asyncio + aiohttp or a framework like Scrapy

2) Parallelize requests

Instead of scraping one site, then the next, send requests concurrently:

  • Threads: good for simple I/O-bound scraping
  • Async: best for lots of requests
  • Multiprocessing: usually not needed unless you’re doing heavy parsing

3) Keep site-specific parsers

Each website has different HTML structure, so create a separate parsing function for each one.


Example: Python with asyncio + aiohttp

import asyncio
import aiohttp
from bs4 import BeautifulSoup

sites = [
    ("https://example.com", "example"),
    ("https://quotes.toscrape.com", "quotes"),
]

async def fetch(session, url):
    async with session.get(url, timeout=20) as response:
        response.raise_for_status()
        return await response.text()

def parse_example(html):
    soup = BeautifulSoup(html, "html.parser")
    return {"title": soup.title.string if soup.title else None}

def parse_quotes(html):
    soup = BeautifulSoup(html, "html.parser")
    quotes = [q.get_text(strip=True) for q in soup.select(".quote .text")]
    return {"quotes": quotes}

async def scrape_site(session, url, site_type):
    html = await fetch(session, url)
    if site_type == "example":
        return url, parse_example(html)
    elif site_type == "quotes":
        return url, parse_quotes(html)
    return url, {}

async def main():
    async with aiohttp.ClientSession() as session:
        tasks = [scrape_site(session, url, site_type) for url, site_type in sites]
        results = await asyncio.gather(*tasks, return_exceptions=True)

        for result in results:
            print(result)

asyncio.run(main())

4) Handle common issues

Rate limiting / blocking

  • Add delays or concurrency limits
  • Rotate user agents carefully
  • Respect robots.txt
  • Use retries with backoff

Different page structures

  • Use different parsers per site
  • Avoid one universal selector for all websites

JavaScript-rendered content

If data loads after page load, use:

  • Playwright for modern automation
  • Selenium if you need browser-like interaction

5) Recommended architecture for many sites

A solid pattern is:

  1. List URLs
  2. Fetch concurrently
  3. Parse with site-specific functions
  4. Store normalized output in JSON/CSV/database

Example output structure:

[
  {"site": "siteA", "url": "...", "data": {...}},
  {"site": "siteB", "url": "...", "data": {...}}
]

6) Best practice: use Scrapy if you’re doing this often

Scrapy gives you:

  • built-in concurrency
  • retries
  • throttling
  • pipelines
  • caching
  • clean spider structure

If you want, I can give you:

  1. a threaded Python example,
  2. a Scrapy project template, or
  3. a Playwright example for JS-heavy sites.

Observation history

Unlock observation history

Create a free Obsurfable account to unlock historical responses, model comparisons, and deeper brand intelligence.

How did Obsurfable measure this prompt?

Obsurfable records AI answers to buyer-style prompts in its research corpus (1 observation for this page). Metrics are distributions over observations, not a single static ranking.

Which AI systems does Obsurfable collect answers from?

OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, and Meta AI.