بدائل Firecrawl المستضافة ذاتيًا على VPS
قارن Draco وHound وFirecrawl المستضاف ذاتيًا من حيث RAM والحاجة إلى متصفح headless وتوافق API، مع تثبيت بإصدار محدد وربط MCP.
ما الذي يجب أن يفعله بديل Firecrawl المستضاف ذاتياً
تتمثل مهمة بديل Firecrawl المستضاف ذاتياً في أخذ URL وإرجاع الصفحة بصيغة Markdown نظيفة يستطيع agent قراءتها. تفرض واجهات API المستضافة رسوماً على كل صفحة، لذلك تزداد الفاتورة كلما زادت رغبة agent في الاستكشاف. ويمكن لـVPS الذي تدفع تكلفته مسبقاً أن ينفذ المهمة نفسها. وتختلف هذه المشاريع حول سؤال واحد: هل يجب تشغيل headless browser (محرك متصفح فعلي يعمل من دون نافذة) على خادمك؟
تحدد الإجابة عن هذا السؤال حجم الذاكرة، وتكلفة كل صفحة، والصفحات التي تعود فارغة. يقارن هذا الدليل بين Draco وHound وإصدار Firecrawl المستضاف ذاتياً، ثم يثبّت الخيار الأخف بإصدار محدد ويربطه بـagent عبر MCP (model context protocol).
المشاريع الأربعة، وماهية كل مشروع فعلياً
Draco هو ملف ثنائي واحد مكتوب بلغة Rust، ومرخّص بموجب MIT أو Apache-2.0. نُشر الإصدار v0.20.5 في 16 July 2026. يطبع draco scrape <url> مستندات Markdown إلى stdout. يشغّل draco serve daemon يستجيب على 127.0.0.1:3002، وهو المنفذ الذي يستخدمه Firecrawl. لا يوفّر صورة حاوية، ولا يبدأ متصفحاً.
Firecrawl self-hosted هو المحرك الذي يقف خلف المنتج المستضاف، ومرخّص بموجب AGPL-3.0. يعرّف docker-compose.yaml سبع خدمات: playwright-service وapi وredis وrabbitmq وnuq-postgres وfoundationdb وfoundationdb-init. تحصل على قائمة انتظار الزحف الفعلية، مقابل تشغيل نظام موزّع صغير.
يوجد Hound في مستودع master-fetch، ويُنشر إلى PyPI باسم hound-mcp، وهو مرخّص بموجب MIT، وإصداره 13.0.1 اعتباراً من 3 August 2026. يحتاج إلى Python 3.11 أو أحدث. وهو خادم MCP أولاً وجالب محتوى ثانياً: يحاول استخدام HTTP عادي، ولا يبدأ متصفح Patchright إلا عندما تفشل عملية الجلب العادي بسبب الحظر.
يوجد Trawl هنا لأن المستخدمين يصادفونه أثناء البحث عن المشاريع الأخرى، ولأنه يؤدي وظيفة مختلفة. يحل تحديات JavaScript وCAPTCHA باستخدام Firefox مُعدّل بصمة المتصفح، كبديل عن FlareSolverr ضمن حزمة وسائط *arr. وهو ليس مستخرجاً لـMarkdown. يشرح القسم التالي عن آداب الاستخدام سبب كون هذا الفرق حاسماً في تحديد ما إذا كان ينتمي إلى حزمة agent لديك أصلاً.
لماذا يكون تجمع المتصفحات سبب توقف خوادم VPS الصغيرة
كل علامة تبويب مفتوحة في المتصفح هي عملية عرض مستقلة تحتفظ بـDOM خاص بها (نموذج كائن المستند) وبـJavaScript heap خاص بها. لذلك تزداد الذاكرة مع عدد الصفحات المفتوحة في اللحظة نفسها، لا مع عدد الصفحات التي جرى جلبها خلال اليوم. يحدد ملفا Compose في هذين المشروعين هذا الاستهلاك ضمن إعداداتهما.
The data behind this chart
[
{
"label": "Firecrawl api",
"memory_limit_gb": 8
},
{
"label": "Firecrawl playwright",
"memory_limit_gb": 4
},
{
"label": "Hound (browser included)",
"memory_limit_gb": 3
}
]يحدد ملف Compose الخاص بـFirecrawl حداً أقصى لذاكرة حاوية api يبلغ 8 GB، ولحاوية Playwright يبلغ 4 GB، مع حدود swap مماثلة. ويحدد ملف Compose الخاص بـHound مقدار 3 GB لحاوية واحدة تتضمن Chromium مضمّناً. هذه حدود قصوى اختارتها المشاريع ونشرتها، وليست قياسات لنظام قليل الاستخدام. كما أن Redis وRabbitMQ وPostgreSQL وFoundationDB تحتاج إلى حصتها فوق أرقام Firecrawl.
لا يفيد تحديد حد أعلى من مقدار RAM المتاح لديك. عندما تنفد موارد الخادم، ينهي kernel قاتل نفاد الذاكرة عمليةً ما، فتختفي حاوية من docker compose ps من دون كتابة خطأ في سجل التطبيق. اقرأ dmesg -T | tail بعد أي إعادة تشغيل لا تستطيع تفسيرها. خصص 8 GB لمكدس Firecrawl الكامل، واعتبر 4 GB الحد الأدنى لصندوق الاختبار. يوضّح حدود الذاكرة في Docker Compose كيفية ضبط الأرقام لكل خدمة.
هناك تفصيل آخر في المتصفح قد يستهلك منك أمسية كاملة. يمنح Docker الحاوية 64 MB من الذاكرة المشتركة في /dev/shm، ويضع Chromium مخازن renderer هناك، لذلك يتعطل عند معالجة الصفحات الثقيلة. يرفع كلا مكدسي المتصفح هذه القيمة: يتضمن ملف Compose الخاص بـHound السطر shm_size: "1gb". انسخ هذا السطر إلى أي image تبنيه حول Playwright.
جودة الاستخراج في الصفحات التي تعتمد بكثافة على JavaScript
في HTML الثابت، مثل مدونة تُعرَض من الخادم أو صفحة توثيق أو مقالة إخبارية، تكون ملفات markdown الناتجة متطابقة تقريباً، وتفوز الأداة الأسرع. يظهر الاختلاف في الصفحات التي تُعرَض من جهة العميل، حيث يكون HTML المُسلَّم مجرد هيكل فارغ، ويصل النص من JavaScript بعد التحميل.
يصعّد Draco المعالجة عبر مستويات. يحلل Tier 0 وTier 1 ملف HTML من دون تشغيل JavaScript إطلاقاً. يشغّل Tier 2 JavaScript الخاص بالصفحة داخل V8 isolate ضمن العملية، وهو محرك JavaScript من دون متصفح يحيط به، وتذكر README أن كود الصفحة لا يحصل هناك على bindings لإمكانات المضيف. يغطي ذلك العديد من تطبيقات الصفحة الواحدة باستخدام جزء من ذاكرة المتصفح. عندما يواجه Draco عائقاً لا يستطيع تجاوزه، يخرج draco scrape بالرمز 3، needs_browser. تحقّق من ذلك في scripts، لأن الملف الفارغ مع رمز خروج يساوي صفراً هو الفشل الذي يلوّث سياق agent بصمت:
draco scrape https://example.com > page.md
echo "exit=$?"تستخدم خدمة playwright-service من Firecrawl متصفح Chromium فعلياً، ولذلك تعرض ما يعرضه المتصفح. لكن الإصدار المستضاف ذاتياً ليس المنتج المستضاف: تذكر الوثائق أن النسخ المستضافة ذاتياً لا تصل إلى Fire Engine، ولذلك تغيب عنها آليات منع الحظر وتدوير عناوين IP المتوفرة في الخدمة السحابية، كما أن نقطتي النهاية /agent و/browser غير مدعومتين. يقع Hound بين الخيارين عن قصد. فهو يجلب المحتوى عبر HTTP ويصعّد المعالجة لكل طلب، كما يغلق المتصفح الدافئ بعد انتهاء مهلة الخمول، ولذلك يبقى الخادم غير النشط قريباً من خط الأساس.
تثبيت Draco بإصدار مثبت
يوثّق ملف README برنامج تثبيت في سطر واحد. اقرأ ما يفعله قبل تمريره إلى shell: فهو يثبّت البرنامج في $HOME/.draco/bin/draco، ويستخدم دائماً الإصدار latest، ولا يتحقق من أي توقيع أو hash. على الخادم، ثبّت الإصدار وتحقق من التنزيل.
cd /tmp
curl -fsSLO https://github.com/0xchasercat/draco/releases/download/v0.20.5/draco-linux-x86-64.tar.gz
curl -fsSLO https://github.com/0xchasercat/draco/releases/download/v0.20.5/SHA256SUMS
sha256sum --ignore-missing -c SHA256SUMSيطبع ذلك draco-linux-x86-64.tar.gz: OK. يعني السطر FAILED أن البايتات الموجودة لديك لا تطابق البايتات التي نشرها المشروع، لذا احذفها وابدأ من جديد.
mkdir -p draco-v0.20.5
tar -xzf draco-linux-x86-64.tar.gz -C draco-v0.20.5
sudo install -m 755 "$(find draco-v0.20.5 -type f -name draco | head -n1)" /usr/local/bin/draco
draco scrape https://example.comيطبع الأمر الأخير صفحة المثال بصيغة markdown خلال أقل بكثير من ثانية. إنّ find ليس للزينة: فتخطيط الأرشيف ليس جزءاً من الواجهة العامة للمشروع، كما أن برنامج التثبيت الرسمي يحدد موقع الملف الثنائي بالطريقة نفسها.
شغّل daemon باستخدام حساب مخصص له بدلاً من مستخدم تسجيل الدخول الخاص بك. اكتب /etc/systemd/system/draco.service:
[Unit]
Description=Draco fetch daemon
After=network-online.target
Wants=network-online.target
[Service]
User=draco
ExecStart=/usr/local/bin/draco serve --host 127.0.0.1 --port 3002 --max-concurrency 4
Restart=on-failure
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.targetsudo useradd --system --no-create-home --shell /usr/sbin/nologin draco
sudo systemctl daemon-reload
sudo systemctl enable --now draco
curl -s http://127.0.0.1:3002/healthيعطي /health استجابة فور بدء daemon بالاستماع. يعني Connection refused أنه لا يستمع، لذا اقرأ journalctl -u draco -n 50. السبب المعتاد هو وجود عملية أخرى تستخدم المنفذ 3002، لأن هذا هو أيضاً المنفذ الافتراضي لـ Firecrawl، ويمكن لـ--port تغيير منفذ أيٍّ منهما. لمزيد من التفاصيل حول ملفات الوحدات: ملفات وحدات وخدمات ومؤقتات systemd.
الآن نفّذ الجلب بالطريقة التي سيستخدمها agent لديك:
curl -X POST http://127.0.0.1:3002/v1/scrape \
-H 'content-type: application/json' \
-d '{"url": "https://example.com", "formats": ["markdown"]}'أبقِ fetch daemon بعيداً عن الإنترنت العام
تُعد Fetch API التي لا تستخدم مصادقة proxy مفتوحاً. يمكن لأي شخص يستطيع الوصول إلى المنفذ أن يجعل خادمك يطلب أي URL عبر عنوان IP الخاص بك. وسيرسل مزود الخدمة بلاغ إساءة الاستخدام إليك، لا إلى ذلك الشخص. تتضمن وثائق Draco أعلام serve من دون API key، لذلك يجب أن توفر الشبكة الحماية. أبقِ إعداد 127.0.0.1 الافتراضي للربط عندما يعمل agent على الخادم نفسه. عندما يكون agent على خادم آخر، ضع الطرفين داخل private tunnel. ويُعد نفق WireGuard تستضيفه بنفسك الخيار المعتاد. اربط الخدمة بعنوان النفق بدلاً من 0.0.0.0. ثم تحقق من جهاز آخر من أن عنوان IP العام لا يستجيب لأي طلب. تشرح أساسيات جدار ufw وحسابات المستخدمين بأقل قدر من الصلاحيات جانبي هذه الحماية.
هل سيتغير رمز وكيلك؟ توافق API عملياً
يستجيب Draco لمسارات Firecrawl v1 التالية: /v1/scrape و/v1/map و/v1/crawl و/v1/batch/scrape و/v1/search، ويذكر ملف README الخاص به أن الحقول غير المعروفة تُقبل ويُتجاهل محتواها. إذا كان أحد الوكلاء يرسل طلبات إلى /v1/scrape، فلن تحتاج إلى تغيير سوى عنوان URL الأساسي. راقب ما تغيّر في الطرف الآخر: تختبر صفحة الاستضافة الذاتية الخاصة بـFirecrawl الآن باستخدام /v2/crawl، بينما تتحدث حزم SDK الحالية باستخدام v2. لذلك، سيطلب عميل v2 موجّه إلى Draco مساراً لا ينشره Draco. اختبر كل استدعاء باستخدام curl قبل تعديل رمز الوكيل، واقرأ محتوى JSON بدلاً من الاكتفاء برمز الحالة، لأن أسماء الحقول هي موضع الاختلاف بين هذه التطبيقات.
ملف Robots.txt، وحدود المعدل، والحد الذي يجب ألا تتجاوزه
يقرأ Draco ملف robots.txt افتراضياً، ويعطّل --ignore-robots ذلك. ويوثّق Firecrawl الإعداد الافتراضي نفسه. اترك الخيارين كما هما. ثم اضبط السرعة بنفسك: يضيف --delay فاصلًا بالمللي ثانية بين الطلبات، ويحدّد --max-concurrency عدد المهام المتوازية، مع كون 8 هو الإعداد الافتراضي للـdaemon. يكون استخدام عدد من اثنتين إلى أربع مهام ألطف على اتصال VPS مشترك، ونادراً ما يكون أبطأ إجمالاً، لأن الموقع الذي يبدأ بفرض حدود للمعدل عليك يكلّفك دقائق أكثر مما توفره زيادة التوازي. خزّن ما تجلبه مؤقتاً، حتى لا تكلّف عملية تشغيل ثانية للوكيل المصدر شيئاً. وهذا أيضاً أرخص بند في التحكم في تكلفة وكيل الذكاء الاصطناعي عليك.
تحديات الوصول موضوع منفصل، وقد صُمّم Trawl لهذا الغرض تحديداً: Cloudflare Turnstile وreCAPTCHA وhCaptcha وGeeTest. تعني صفحة التحدي أن الموقع يرفض حركة المرور الآلية بوضوح. إن تجاوزها يضعك في مخالفة شروط استخدام الموقع، وفي بعض الأماكن قد يضعك في مخالفة القانون، لذلك يغطي هذا الدليل بنية الجلب ويتوقف عند ذلك. التقنيات نفسها التي تتجاوز صفحة التحدي هي التي يراقبها مالكو المواقع ويحظرونها، ما يجعل أي خط أنابيب يعتمد عليها هشاً، فضلاً عن كونه مزعجاً. عندما يكون المصدر مهماً إلى هذا الحد، ابحث عن موجز RSS الخاص به، أو واجهة API العامة، أو تصدير جماعي. كل خيار منها أقل تكلفة في التشغيل، ولا يتعطل في الأسبوع الذي يغيّر فيه الموقع صفحة التحدي.
وصّل الوكيل عبر MCP
MCP (model context protocol) هو الواجهة التي يستخدمها الوكيل لاستدعاء أداة. يحدّد الغلاف الذي يعمل النموذج ضمنه الأدوات التي تصل إلى النموذج أصلاً، وما إذا كان مسموحاً له باستدعاء أداة من دون سؤالك أولاً. لذلك، لا يمثل تشغيل الـdaemon للاستماع سوى نصف عملية الربط. يضم Draco خادم MCP في الملف الثنائي نفسه، ويعمل عبر stdio:
{ "mcpServers": { "draco": { "command": "draco", "args": ["mcp"] } } }تظهر الأدوات للوكيل باسم draco_scrape وdraco_search ومجموعة draco_interact_*. لا يعمل stdio إلا عندما تعمل عملية الوكيل والملف الثنائي على الجهاز نفسه، لأن وسيلة النقل تستخدم الإدخال القياسي لتلك العملية. بالنسبة إلى وكيل يعمل على مضيف آخر، يوفّر Hound بروتوكول MCP عبر HTTP بدلاً من ذلك: ينشر hound --http --host 127.0.0.1 --port 8765 نقطة نهاية عند http://127.0.0.1:8765/mcp، ويمكنك الوصول إليها عبر النفق. يوضّح تشغيل خوادم MCP على VPS خيارات النقل وما يجب إتاحته.
اجمع بين الجلب والبحث. الوكيل الذي يستطيع الجلب فقط ينتظر منك تزويده بعناوين URL. أضف مثيل بحث SearXNG مستضافاً ذاتياً ليتمكن من العثور عليها بنفسه، بالطريقة نفسها المستخدمة في مهارة البحث في المتصفح المبنية على SearXNG. بعد تشغيل الخدمة، تصبح خدمة مشتركة لأي من وكلاء الذكاء الاصطناعي المستضافين ذاتياً الذين تشغّلهم. إذا كان جانب الوكيل هو الجزء الذي لا تثق به أكثر، فإن كتابة حلقة وكيل صغيرة يدوياً أولاً توضّح مكان توصيل أداة الجلب وما الذي يفعله النموذج مع Markdown الذي يستلمه.
FAQ
هل أحتاج إلى متصفح عديم الواجهة لجلب الصفحات لوكيل ذكاء اصطناعي؟
ليس لمعظم الصفحات. تُجلب الوثائق والمقالات الإخبارية والمدونات التي تُنشأ على الخادم كاملةً عبر طلب HTTP عادي، يتبعه تحويل HTML إلى Markdown. وهذا ما يفعله Draco في مستوياته الدنيا بزمن يقارب 300 ms لكل صفحة من دون متصفح، وفق أرقام المشروع نفسه. تحتاج التطبيقات التي تُنشأ على العميل إلى متصفح، لأن HTML المُسلَّم إليها يكون هيكلاً فارغاً. ويغطي V8 isolate في Draco جزءاً كبيراً من هذه الحالات من دون عملية متصفح، ويخرج بالرمز 3، needs_browser، عندما يعجز عن ذلك.
ما مقدار RAM الذي يحتاج إليه Firecrawl المستضاف ذاتياً على VPS؟
يحدد ملف compose سقفاً قدره 8 GB لحاوية api، و4 GB لحاوية Playwright. كما تشغّل الحزمة نفسها Redis وRabbitMQ وPostgreSQL وFoundationDB. خطط لتوفير 8 GB. في خادم بسعة 2 GB، ينهي قاتل نفاد الذاكرة في kernel عمل الحاويات تحت الحمل. وتكون أول علامة على ذلك حاوية أُعيد تشغيلها في docker compose ps من دون معلومات مفيدة في سجل التطبيق، لذا أكّد الأمر باستخدام dmesg -T | tail.
هل يُعد Draco بديلاً مباشراً لـ Firecrawl API؟
هو قريب من ذلك بالنسبة إلى نقاط النهاية v1. فهو يخدم /v1/scrape و/v1/map و/v1/crawl و/v1/batch/scrape و/v1/search، ويتجاهل حقول الطلب التي لا يعرفها. لذلك يحتاج العميل المكتوب لـ Firecrawl v1 عادةً إلى تغيير عنوان base URL فقط. لكنه ليس المنتج المستضاف: لا توجد خلفه مجموعة proxy مُدارة، كما أن مسارات Firecrawl الأحدث في v2 ليست ضمن الواجهة المتاحة. تحقّق أولاً من كل استدعاء يجريه وكيلك باستخدام curl.
هل يعني استضافة أداة الكشط ذاتياً أنني أستطيع تجاهل robots.txt؟
لا. لا يغيّر مكان تشغيل الكود شيئاً مما نشره الموقع أو مما تسمح به شروطه. يحترم كل من Draco وFirecrawl ملف robots.txt افتراضياً، ويوجد خيار التجاوز للمواقع التي تملكها أو التي منحتك إذناً خطياً لكشطها. تُطبَّق حدود المعدل في الطرف الآخر على أي حال، لذا يحافظ --delay المهذب مع خفض التزامن على عمل عنوان IP الخاص بك. وأي حزمة لا تعمل إلا بتجاوز جدار التحديات هي حزمة قد تتوقف من دون تحذير.