Prompt
How do I create an automated web scraping workflow?
Latest observation
To create an automated web scraping workflow, think of it as a pipeline with 6 parts:
- Define the target
- Build the scraper
- Store the data
- Automate execution
- Monitor and recover from failures
- Keep it compliant and maintainable
1) Define exactly what you need
Before writing code, decide:
- Which pages or endpoints to scrape
- What fields you want
- How often you need updates
- Whether the site is static or JavaScript-rendered
- How much data you expect
If the data is available through an API or structured feed, use that instead of scraping HTML.
2) Choose the right tools
Common options:
- Requests + BeautifulSoup: good for static pages
- Scrapy: best for larger, production-style crawlers
- Playwright / Selenium: useful for JavaScript-heavy sites
- Pandas: for cleaning and storing tabular data
Typical stack:
- Python
- Requests
- BeautifulSoup or Scrapy
- Playwright for dynamic pages
- SQLite/PostgreSQL/CSV/JSON for storage
- Cron/Airflow/GitHub Actions for scheduling
3) Build the scraper
A basic static-page workflow looks like this:
- Send an HTTP request
- Parse the HTML
- Extract the required data
- Clean and normalize it
- Save it to a file or database
Example with Python:
import requests
from bs4 import BeautifulSoup
import csv
url = "https://example.com/products"
headers = {"User-Agent": "Mozilla/5.0"}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
items = []
for card in soup.select(".product-card"):
name = card.select_one(".name").get_text(strip=True)
price = card.select_one(".price").get_text(strip=True)
items.append({"name": name, "price": price})
with open("products.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["name", "price"])
writer.writeheader()
writer.writerows(items)
For JavaScript-rendered pages, use Playwright:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://example.com/products", wait_until="networkidle")
html = page.content()
browser.close()
4) Automate it
Once the scraper works locally, schedule it.
Simple scheduling options
- Cron on Linux/macOS
- Task Scheduler on Windows
- GitHub Actions for lightweight cloud runs
- Airflow for complex pipelines
- Prefect / Dagster for modern workflow orchestration
Example cron job to run every day at 2 AM:
0 2 * * * /usr/bin/python3 /path/to/scraper.py
5) Add reliability features
Automated scrapers should handle failures gracefully:
- Retry on temporary failures
- Use timeouts
- Log errors
- Detect layout changes
- Save partial progress
- Respect rate limits
- Rotate or back off requests if needed
Good practices:
- Set a realistic
User-Agent - Use exponential backoff for retries
- Avoid hammering the site
- Check HTTP status codes
- Validate extracted data before saving
Example retry approach with tenacity:
from tenacity import retry, stop_after_attempt, wait_exponential
import requests
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
def fetch(url):
r = requests.get(url, timeout=20)
r.raise_for_status()
return r.text
6) Store and process the data
Depending on your use case, store data in:
- CSV: simple and portable
- JSON: good for nested data
- SQLite: easy local database
- PostgreSQL/MySQL: better for production
- S3 or cloud storage: for large files
Then clean and transform it:
- Remove duplicates
- Standardize dates/currencies
- Convert text to numeric types
- Compare with previous runs to detect changes
7) Monitor the workflow
Automated scraping can break when websites change. Add:
- Logging
- Alerts on failure
- Checks for empty output
- Data quality rules
- Notifications via email/Slack
For example:
- “If fewer than 10 rows are extracted, alert me”
- “If parsing fails, send a message”
8) Respect legal and ethical constraints
Make sure you:
- Follow the site’s Terms of Service
- Check
robots.txt - Avoid private, protected, or copyrighted data misuse
- Don’t bypass access controls or CAPTCHAs
- Keep request rates reasonable
If you need data at scale, consider requesting permission or using an official API.
A practical architecture
A common production setup:
- Scheduler: Cron / Airflow
- Scraper: Python script or Scrapy spider
- Storage: PostgreSQL
- Logging: Python logging + file/CloudWatch
- Alerts: Email or Slack
- Dashboard: Optional BI tool or notebook
If you want a fast starting point
Use this sequence:
- Inspect the page in browser dev tools
- Identify selectors or API calls
- Write a small scraper
- Save results locally
- Add retries and logging
- Schedule it
- Add monitoring and alerts
If you want, I can also provide:
- a complete Python example
- a Scrapy project template
- a Playwright-based scraper
- or a Docker + cron workflow for automation