Skip to main content

Cron Jobs for Web Scraping: Schedule Scrapers on Linux 2026

· 4 min read
Yassine El Haddad
Software Developer & Automation Specialist

I build production AI agents, web scrapers, and automation pipelines. Most of what I publish here comes from the actual problems they run into: proxies that get banned, anti-bot stacks that fingerprint your client, RAG that drifts when the underlying data moves. Stack: Python, TypeScript, Go, FastAPI, LangChain, Crawlee, Playwright, deployed on AWS, GCP, and Cloudflare.

Schedule web scrapers with cron: use the 5-field crontab format, set environment variables correctly, and log output. Prefer systemd timers for modern Linux. For managed scheduling with no server, use Apify.

Crontab Syntax (5 Fields)

┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-7, 0 and 7 = Sunday)
│ │ │ │ │
* * * * * command

Special characters: * (any), , (list), - (range), */n (every n units).

Practical Cron Examples for Scrapers

# Edit crontab
crontab -e
# Every day at 2:00 AM
0 2 * * * /opt/scrapers/daily-price-check.sh >> /var/log/price-scraper.log 2>&1

# Every 6 hours
0 */6 * * * /opt/scrapers/hourly-feed.sh >> /var/log/feed-scraper.log 2>&1

# Every Monday at 3:00 AM (weekly full crawl)
0 3 * * 1 /opt/scrapers/weekly-full-crawl.sh >> /var/log/full-crawl.log 2>&1

# Every 15 minutes (aggressive — use rate limiting)
*/15 * * * * /opt/scrapers/quick-check.sh >> /var/log/quick-check.log 2>&1

Environment Variables in Cron

Cron runs with a minimal environment. Set PATH and load .env inside your script.

# Crontab: set SHELL and PATH
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin
MAILTO=ops@example.com

0 2 * * * /opt/scrapers/run.sh >> /var/log/scraper.log 2>&1
# run.sh — load env before execution
#!/bin/bash
set -e
source /opt/scrapers/.env
cd /opt/scrapers
node scrape.js

Logging Cron Output

Always capture stdout and stderr. Rotate logs to avoid disk fill.

# Redirect both streams
0 2 * * * /opt/scrapers/run.sh >> /var/log/scraper.log 2>&1

# Or split
0 2 * * * /opt/scrapers/run.sh > /var/log/scraper.log 2> /var/log/scraper.err

Add logrotate:

# /etc/logrotate.d/scraper
/var/log/scraper*.log {
daily
rotate 7
compress
missingok
}

Preventing Overlapping Runs

Use flock to ensure only one instance runs at a time.

# In crontab
0 2 * * * flock -n /tmp/daily-scraper.lock /opt/scrapers/daily.sh >> /var/log/scraper.log 2>&1

-n = non-blocking; if lock is held, cron skips this run.

systemd Timers as Modern Alternative

systemd timers offer better logging, dependency management, and random delays. Use them on systemd-based Linux.

# /etc/systemd/system/scraper-daily.service
[Unit]
Description=Daily price scraper

[Service]
Type=oneshot
User=scraper
WorkingDirectory=/opt/scrapers
ExecStart=/opt/scrapers/daily.sh
# /etc/systemd/system/scraper-daily.timer
[Unit]
Description=Run scraper daily at 2 AM

[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=300
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl enable scraper-daily.timer
sudo systemctl start scraper-daily.timer

Common Cron Mistakes

MistakeFix
No PATHSet PATH in crontab or script
No stderr captureUse 2>&1
Overlapping runsUse flock or systemd
Wrong userRun crontab -u scraper -e for service user
Dependencies not loadedSource .env or set vars in crontab
No idempotencyDesign scrapers to be safely re-runnable

Apify Scheduling as Managed Alternative

Apify provides built-in scheduling. No cron, no server. Set a schedule in the Actor or via API. Runs execute in the cloud with proxy rotation and built-in storage.

// Apify API: create scheduled run
await apifyClient.schedules().getOrCreate('my-daily-scraper', {
crontab: '0 2 * * *', // 2 AM daily
action: 'RUN',
actorId: 'your-actor-id',
});
Apify Affiliate Banner 728x90Apify Affiliate Banner 728x90Apify Affiliate Banner 300x50Apify Affiliate Banner 300x50
Next step

Use flock to prevent overlap. Log everything. Prefer systemd timers on modern Linux. For zero server ops, use Apify scheduling.

Frequently Asked Questions

Use crontab -e and add a line like '0 2 * * * /opt/scrapers/run.sh >> /var/log/scraper.log 2>&1'. Or use systemd timers for better logging.

crontab is the Linux scheduler. Five fields: minute, hour, day-of-month, month, day-of-week. Asterisks mean 'every'.

Depends on data freshness needs. Daily for most use cases. Hourly for feeds. Every 15 min only if rate limits and target ToS allow.

Cron runs with minimal env. Set PATH, source .env in the script, and capture stderr with 2>&1 to debug.

Common mistakes and fixes

Cron job runs but scraper fails silently

Redirect stderr: 0 2 * * * /opt/scraper/run.sh >> /var/log/scraper.log 2>&1

Environment variables missing in cron

Source .env in the script or define vars in crontab: SHELL=/bin/bash, PATH=/usr/bin:/usr/local/bin

Overlapping runs when job exceeds interval

Use flock: flock -n /tmp/scraper.lock /opt/scraper/run.sh