أتمتة فحص الروابط المكسورة بـ lychee و cron
مستوى القارئ: متوسط
هتكسب من المقال ده نظام بسيط يكشف الروابط المكسورة كل يوم قبل ما المستخدم أو محرك البحث يكتشفها. الفكرة: سكربت صغير على VPS يشغل lychee على sitemap، يحفظ تقريرًا، ويرسل تنبيه Slack لو ظهر 404 أو timeout.
المشكلة باختصار
لو عندك موقع محتوى فيه 180 صفحة، وكل صفحة فيها 5 إلى 10 روابط داخلية وخارجية، فأنت بتتعامل مع حوالي 900 إلى 1800 رابط. فحص الرقم ده يدويًا مرة كل أسبوع طريقة بتفشل في نقطتين: بتاخد وقت، وبتكتشف المشكلة بعد ما تكون أثرت على القارئ.
اللي بيحصل فعلاً إن رابط قديم في مقال شغال من سنة يتحول إلى 404، أو وثائق أداة خارجية تغير المسار، أو صفحة تحميل تبقى بطيئة وتعمل timeout. النتيجة مش كارثية في أول يوم، لكنها بتتراكم: تجربة أسوأ، ثقة أقل، وإشارات SEO أضعف لو الأخطاء بقت كثيرة.
ليه lychee مناسب للحالة دي
lychee أداة فحص روابط مفتوحة المصدر تقدر تفحص ملفات Markdown و HTML و URLs مباشرة، وتطلع نتيجة واضحة في الطرفية أو JSON. حسب توثيق المشروع، الأداة تدعم تجاهل روابط معينة، ضبط timeout، وعدد المحاولات. ده مهم لأن بعض المواقع الخارجية بتفشل مؤقتًا، ومش كل فشل معناه إن عندك مشكلة حقيقية.
ركز هنا: أفضل طريقة مش إنك تفشل النشر عند أول رابط خارجي بطيء. الأفضل إنك تعمل فحص يومي منفصل، وتخلي التقرير يقولك الرابط، نوع الخطأ، والصفحة المتأثرة. المكسب إنك تقلل الضوضاء. الـ trade-off هنا إن الخطأ ممكن يفضل ساعات قبل ما يتصلح، بدل ما يوقف الـ deploy فورًا.
الافتراض إن عندك VPS صغير أو سيرفر لينكس شغال بالفعل، وموقعك بيطلع sitemap.xml. لو الموقع صغير جدًا، 20 صفحة مثلًا، نفس الفكرة تشتغل لكن العائد أقل.
الإعداد العملي خطوة بخطوة
- اعمل مجلد للتقارير والسكربت على السيرفر.
- شغل
lycheeمن Docker عشان ما تربطش نفسك بتثبيت محلي. - اقرأ sitemap، واستخرج الروابط، ثم افحصها.
- لو الفحص فشل، ابعت ملخص إلى Slack webhook.
- شغل السكربت يوميًا باستخدام
cron.
sudo mkdir -p /opt/link-check/reports
sudo nano /opt/link-check/run.sh
حط السكربت ده. غيّر SITE_URL و SLACK_WEBHOOK_URL بالقيم المناسبة عندك.
#!/usr/bin/env bash
set -euo pipefail
SITE_URL="https://example.com"
SITEMAP_URL="$SITE_URL/sitemap.xml"
REPORT_DIR="/opt/link-check/reports"
TODAY="$(date +%F)"
REPORT_FILE="$REPORT_DIR/lychee-$TODAY.txt"
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/XXX/YYY/ZZZ"
mkdir -p "$REPORT_DIR"
# lychee يرجع exit code غير صفر لو لقى روابط مكسورة.
set +e
docker run --rm lycheeverse/lychee:latest \
--max-concurrency 16 \
--timeout 20 \
--retry-wait-time 2 \
--max-retries 2 \
"$SITEMAP_URL" > "$REPORT_FILE" 2>&1
STATUS=$?
set -e
if [ "$STATUS" -ne 0 ]; then
SUMMARY="$(tail -n 25 "$REPORT_FILE" | sed 's/"/\\"/g')"
curl -sS -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"Broken links found on $SITE_URL:\n\n$SUMMARY\"}" \
"$SLACK_WEBHOOK_URL" > /dev/null
fi
exit 0
sudo chmod +x /opt/link-check/run.sh
sudo crontab -e
أضف السطر ده لتشغيل الفحص كل يوم الساعة 7 صباحًا بتوقيت السيرفر:
0 7 * * * /opt/link-check/run.sh
سيناريو واقعي بالأرقام
خلينا نقول عندك مدونة تقنية بـ 220 مقال، وكل مقال فيه متوسط 7 روابط. ده حوالي 1540 رابط. على VPS عادي بذاكرة 1GB، فحص الرقم ده بـ concurrency 16 ممكن يخلص في 2 إلى 5 دقائق، حسب سرعة المواقع الخارجية. لو رفعت concurrency إلى 64، ممكن تنزل المدة إلى دقيقتين، لكنك هتزود ضغط الشبكة واحتمال false positives بسبب rate limiting من مواقع خارجية.
بدل ما تقضي 45 دقيقة أسبوعيًا في فحص عينة عشوائية، السكربت بيكلفك تقريبًا 5 دقائق إعداد أول مرة، وبعدها دقيقة متابعة لما يجيلك تنبيه. بتكسب اكتشاف أسرع. بتخسر إنك محتاج تحافظ على Slack webhook وتراجع التقرير بدل الاعتماد على إحساسك.
الـ trade-offs وما يجب الانتباه له
- Docker بدل تثبيت lychee محليًا: بتكسب reproducibility، وبتخسر تحميل image أول مرة.
- فحص يومي بدل فحص مع كل deploy: بتكسب تنبيهات أقل إزعاجًا، وبتخسر اكتشاف فوري داخل pipeline.
- timeout يساوي 20 ثانية: مناسب لمعظم الروابط الخارجية. أقل من 10 ثواني ممكن يطلع إنذارات كاذبة.
- max-concurrency 16: رقم محافظ. لو موقعك كبير جدًا جرب 32، لكن راقب false positives.
لو عايزها تدعم مواقع متعددة، اعمل ملف sites.txt وحلقة while read تشغل الفحص لكل موقع. بس متبدأش بكده. ابدأ بموقع واحد، افهم الضوضاء، وبعدها وسّع.
متى لا تستخدم هذه الطريقة
لا تستخدم الطريقة دي لو موقعك خلف login بالكامل، لأن lychee مش هيشوف الروابط بنفس جلسة المستخدم. لا تستخدمها كبديل لاختبارات end-to-end لو الروابط بتتولد بعد تفاعل JavaScript معقد. ولا تعتمد عليها وحدها لو عندك SLA رسمي؛ في الحالة دي محتاج مراقبة uptime منفصلة مثل Better Stack أو Uptime Kuma.
مصادر اعتمدت عليها
- توثيق lychee على GitHub لفهم خيارات الفحص والـ exit codes.
- توثيق docker run لتشغيل الأداة داخل container بدون تثبيت محلي.
- توثيق Slack Incoming Webhooks لبناء تنبيه بسيط عند وجود روابط مكسورة.
- توثيق crontab لصيغة الجدولة اليومية.
الخطوة التالية
الخطوة التالية: شغّل السكربت يدويًا مرة واحدة على موقعك، وافتح آخر 25 سطرًا من التقرير. لو لقيت أكثر من 5 روابط خارجية فاشلة بسبب timeout فقط، زوّد --timeout إلى 30 ثانية قبل ما تعتبرها أخطاء حقيقية.