selectolax، بقياس فعلي: محلّل HTML سريع يتفوّق على BeautifulSoup ويعادل lxml

آخر تحديث في July 17, 2026
selectolax، بقياس فعلي: محلّل HTML سريع يتفوّق على BeautifulSoup ويعادل lxml
ملخص بالذكاء الاصطناعي
تُقيّم هذه المراجعة selectolax مقارنةً بـ lxml وBeautifulSoup وparsel وخيارات البنية الخلفية المختلفة عبر أحجام صفحات متعددة، وتغطي تغطية محددات CSS واستهلاك الذاكرة وسلوك HTML المشوّه والحالات الحدّية. وتؤكد أن selectolax أسرع بكثير من BeautifulSoup ومنافس قوي لـ lxml في مهام التحليل والاستخراج الكاملة، مع إظهار أن lxml قد يكون أسرع في التحليل البحت في بيئة الاختبار هذه. كما تشرح المقالة محركي Lexbor وModest، وثغرات محددات CSS، ومشكلة محتوى template، وفوائد الذاكرة، وتفاصيل الترخيص، ومتى يكون selectolax بديلًا قويًا لسير العمل الأبطأ في Python.

كل مقال يزعم أنه يتكلم عن "أسرع محلّل HTML في Python" غالبًا ينتهي عند selectolax، ثم يختصر الحكاية كلها بجملة "أسرع بكثير من BeautifulSoup". وهذا صحيح جزئيًا. لكن الشيء الذي لا يذكره أغلبهم هو ماذا يحدث عندما تضع selectolax في مواجهة lxml مباشرة — لأن كلمة "الأسرع" هنا تحتاج نجمة صغيرة.

لذلك سويت benchmark بشكل صحيح: selectolax (بكلتا البنيتين الخلفيتين) أمام lxml، وBeautifulSoup على html.parser وعلى lxml، وparsel، عبر خمس أحجام صفحات من 1 KB إلى 10 MB، مع أخذ الوسيط الحسابي لثلاث تشغيلات مستقلة لكل قياس. selectolax تفوق على BeautifulSoup بفارق كبير، وتعادل تقريبًا مع lxml الخام — ثم خسر مرحلة التحليل البحت لصالح lxml. كل الأرقام أدناه أولية ومأخوذة من جهاز واحد فقط (macOS arm64، Python 3.14.2)؛ والسكريبتات محفوظة في المستودع، لذلك شغّلها على جهازك قبل أن تستشهد بي.

ما هو selectolax فعليًا، وما الذي ليس كذلك

selectolax هو ربط Python لمحركين مكتوبين بـ C — Modest وLexbor — يقرآن HTML5 ويخلّيانك تستعلم عنه عبر CSS selectors. هو ليس زاحف، ولا متصفح، ولا "مستخرج بيانات" بضغطة زر. هو الأداة التي تمرر لها كتلة HTML بعد ما تكون جبتها مسبقًا. والوصف المختصر من المطور نفسه هو: "محلل HTML5 سريع مع محددات CSS، مكتوب بـ Cython، ويستخدم محركي Modest وLexbor."

وفيه بنيتان خلفيتان، والفرق بينهم أهم مما توحي به الوثائق:

  • LexborHTMLParser (محرك Lexbor) — وهذا هو الخيار الموصى به في README اعتبارًا من 2024.
  • HTMLParser (محرك Modest) — النسخة الأصلية، والتي "لم يعد المحرك C الأساسي لها قيد الصيانة" بحسب README نفسه.

قبل ما ندخل في السرعة، فيه كم معلومة مفيدة. حتى لقطة المستودع المأخوذة في 2026-07-10، كان لدى selectolax 1,653 نجمة، وآخر إصدار هو v0.4.10 (مايو 2026)، بينما PyPI يحدده ليعمل مع Python >=3.9,<3.15. والتثبيت هو الجزء الأقل دراما هنا: أمر pip install selectolax نزل wheel جاهز بحجم 2.3 MB من نوع cp314 واشتغل فورًا على Python 3.14 — من دون تنزيل متصفح، ومن دون خطوة doctor, ومن دون ترجمة محلية. وهذه هي ميزة المحلل الخالص مقارنة بأداة تعتمد على المتصفح. فقط تستورد وتبدأ.

وفيه نقطة ترخيص مهمة ما ينفع تندفن: ربط Python نفسه مرخّص بـ MIT، لكن ملف wheel يضم المحركات المترجمة، وهؤلاء لهم تراخيصهم الخاصة — Modest مرخّص LGPL-2.1، وLexbor مرخّص Apache-2.0. يعني عبارة "selectolax مرخّص بـ MIT" صحيحة لشفرة Python فقط، لكنها غير كاملة بالنسبة للثنائي الذي ستوزعه فعليًا. إذا كان فريقك القانوني مهتمًا بالمكونات المعاد توزيعها، فهذه هي النقطة التي لازم تنتبه لها.

سؤال السرعة، والجواب بالأرقام الفعلية

هذه هي المهمة التي قستها: تحليل سلسلة HTML، واستخراج نص كل <h3 class="title">، واستخراج href لكل <a>. تم تسجيل زمن الاستجابة بالمللي ثانية، مع أخذ الوسيط الحسابي عبر ثلاث تشغيلات مستقلة؛ وكان التفاوت بين التشغيلات أقل من نحو 5% في معظم الأحجام بالنسبة للمحللات المعتمدة على C. قبل قياس أي خلية، كنت أختزل ناتج كل محلل إلى تجزئة محتوى حتى أتأكد من أن ما أحد يقلل شغله بصمت — وفي هذه الصفحات تطابقت النتائج الست كلها في جميع الأحجام، فالمقارنة هنا عادلة فعلًا. البيانات الكاملة موجودة في الملف الملتزم bench_parse.json.

selectolax أسرع من BeautifulSoup بـ 12-17 مرة عبر أحجام الصفحات المختلفة

الصفحةselectolax (Lexbor)selectolax (Modest)lxmlparselBS (lxml)BS (html.parser)
1 KB0.0270.0290.0360.0440.2810.323
10 KB0.1600.1710.1660.2281.7052.049
100 KB1.4641.5651.4232.02016.520.6
1 MB14.90116.914.17720.9181.9232.6
10 MB159.9247.9172.9231.92261.62788.7

مقارنةً بـ BeautifulSoup: نحو 12-17 مرة، والسمعة المنتشرة تقلل الفارق

إذا حولنا الأرقام إلى نسب، فـ selectolax-Lexbor يطلع أسرع بنحو 12 مرة من BeautifulSoup(html.parser) عند صفحة بحجم 1 KB، ويصل إلى نحو 17 مرة عند 10 MB، وهو أيضًا أسرع بنحو 10-14 مرة من BeautifulSoup(lxml) عبر نفس المدى. الرقم المتداول على الإنترنت — "selectolax أسرع بنحو 4-5 مرات من BeautifulSoup" — قليل جدًا إذا كنت تقارنه مع html.parser، ويقترب من الواقع فقط إذا كنت تقارن مع BeautifulSoup المبني على lxml. المضاعف الحقيقي يعتمد على أي نسخة من BeautifulSoup تقصد، وكمية البيانات التي تستخرجها من كل صفحة.

وهذا يتماشى أيضًا مع معيار README نفسه، الذي يوحي بفارق 25.5 مرة أمام BeautifulSoup(html.parser). وما في تناقض هنا. مهمة README (العنوان، الروابط، السكربتات، والميتا من صفحات رئيسية صغيرة) تقوم باستخراج أقل على الصفحات الصغيرة، وهذا يجعل الكلفة الثابتة لـ BeautifulSoup في كل عملية تحليل تظهر بشكل أوضح. وبصياغة أكثر تحفظًا: selectolax أسرع غالبًا بنحو 10-15 مرة من BeautifulSoup في أعمال التحليل والاستخراج الواقعية، والفارق يكبر مع الصفحات الصغيرة والاستخراج الخفيف.

إذا كانت عنق الزجاجة عندك حاليًا هي كمية كود BeautifulSoup ينهش الصفحات، فهذه النقلة ستدفع ثمنها مرة واحدة ثم تستفيد منها. وهذه حالة واضحة. لكن الحالة التالية هي الأشد جدلًا.

مقارنةً بـ lxml: تعادل — وlxml يتفوق في الجزء الذي ينساه الجميع

ارجع لصفّي 100 KB و1 MB. ستلاحظ أن Lexbor وlxml متقاربان ضمن نحو 5%، وأن نطاقات كل تشغيل تتداخل، ووفق منهجيتي فهذا تعادل — لا فائز، ولا "أسرع". الموضع الوحيد الذي يتقدم فيه selectolax بوضوح هو صفحة 10 MB (159.9 ms مقابل 172.9 ms، بفارق 8.1% ومع عدم تداخل النطاقات). إذن في المهمة الكاملة يتعادل selectolax مع lxml، ولا يتفوق عليه إلا في أضخم المستندات.

selectolax يعادل lxml في المهمة الكاملة لكن lxml يتفوق في التحليل البحت بنسبة 33-34 بالمئة

بعد ذلك فصلت بناء الشجرة عن استعلامات CSS، وطلعت النتيجة بالعكس مما كثير من الكتّاب يلتقطونه. في التحليل البحت، من دون أي استعلامات، كان lxml أسرع بشكل ثابت بنحو 33-34% من selectolax-Lexbor على هذا الجهاز — 77.9 ms مقابل 116.6 ms عند صفحة 10 MB. أما في المهمة الكاملة، فهما يقتربان من بعض على أي حال، وتخمين عملي عندي — وليس شيئًا أثبته بتجربة سببية — هو أن استعلام CSS في هذه الصفحات يمثل جزءًا صغيرًا من الزمن الكلي، لذلك يتلاشى تفوق lxml في مرحلة التحليل حتى تتقارب الأرقام النهائية.

هذه أكثر نقطة قابلة للهجوم في هذه المراجعة، وأحب أوضح السبب. لأنها تعاكس الحكمة الشائعة، والمعيار المنشور الوحيد الذي وجدته ويفصل التحليل البحت — aows.jpt.sh — يقول العكس، أي أن selectolax أسرع بنحو 4 مرات. لذلك شددت النتيجة: هي محصورة على منصة واحدة (macOS arm64، Python 3.14، ملفات cp314 جاهزة مسبقًا — ولم أختبر Linux x86_64 ولا البناء من المصدر)، وتم التحقق منها عبر أربع أحجام صفحات وبقيت ثابتة في كلها، كما أعدت التحقق منها باستخدام واجهتي lxml مختلفتين للتأكد من عدم وجود أثر من الواجهة نفسها. كلتا واجهتي lxml تفوقت على selectolax-Lexbor في جميع الأحجام. أنا لا أطرح عبارة "lxml أسرع في التحليل" كحقيقة نهائية، بل كشيء أظهره هذا القياس، مع إرفاق السكربت، رغم أن أغلب الأرقام المنشورة تقول غير ذلك. جرّبه على جهازك.

فيه زاوية ثانية: عند استعلام 100,000 عنصر <a> في صفحة مسطحة، تعادل lxml وselectolax-Modest (33.30 ms مقابل 34.19 ms، مع تداخل النطاقات)، بينما تأخر selectolax-Lexbor عنهما بنحو 15%. الشيء المشترك بين محركات C الثلاثة هو أنها أسرع من parsel أو BeautifulSoup بنحو 5-7 مرات في الاستعلامات الكثيفة، لأن نموذج "كائن Python لكل عقدة" هو العبء الحقيقي هناك. لذلك عبارة "selectolax هو الأسرع في اختيار CSS الكثيف" لا تصمد أيضًا — فـ Modest يعادل lxml فقط، وLexbor يخسر أمامه.

الخلاصة التي أقدر أدافع عنها فعلًا: تفوق selectolax على lxml ليس تفوقًا عامًا في السرعة الشاملة. هو يفوز فقط في الصفحة الأكبر جدًا. وحجته الأساسية ليست السرعة المطلقة، بل أمور ثانية — سهولة الواجهة، والتعامل مع المدخلات الرديئة، وحداثة CSS — وهذا هو مجال بقية المراجعة.

الذاكرة وبدء التشغيل البارد: رتّب حسب RSS، لا حسب ملف التعقب

الذاكرة هنا هي المكان الذي اضطررت فيه أصحح أرقامي السابقة، وهذا التصحيح هو قلب القصة. عند القياس كنقص في RSS على صفحة 10 MB مع إيقاف tracemalloc، يستخدم BeautifulSoup ذاكرة أكبر بنحو 1.5-1.8 مرة من selectolax أو lxml — ويتراوح الفارق من 1.51 مرة (BS-lxml عند 218.4 MB مقابل Lexbor عند 144.6 MB) إلى 1.75 مرة عند الحد الأعلى. أما selectolax وlxml فيقعان ضمن الطبقة الأخف؛ وlxml هو الأخف من حيث RSS.

selectolax ضمن طبقة الذاكرة المقاسة بـ RSS مع إيقاف أداة التتبع

في مرة سابقة قلت "حوالي 3 مرات"، وكان هذا الرقم خاطئًا لسبب تعليمي: كنت قسته بينما tracemalloc شغال، وتتبع كل عملية تخصيص يضاعف تقريبًا الـ RSS الظاهري للمحلل الأكثر تخصيصًا. لذلك النصيحة هنا لأي أحد يقيس ذاكرة المحللات: رتب حسب RSS وأوقف أداة التتبع. ترتيب المحللات حسب ذروة tracemalloc يظلم خصوصًا المحللات المعتمدة على C — فقد جعل selectolax-Lexbor يبدو أثقل من Modest، بينما هما في RSS الحقيقي متقاربان. BeautifulSoup هو فعلًا الأثقل هنا؛ لكنه ليس أثقل بثلاثة أضعاف كما أوحى القياس الملوّث.

بدء التشغيل البارد ليس أهم شيء، لكنه حقيقي: يستورد selectolax خلال نحو 14 ms، وهو قريب من lxml، وأسرع بنحو 2.3 مرة من bs4 أو parsel. إذا كنت تبني أداة CLI أو دالة serverless يكون فيها وقت الاستيراد جزءًا من كل تشغيل، فهذه فجوة تستاهل الذكر.

تغطية محددات CSS: قوية، لكن مع بعض الثغرات الحقيقية

اختبرت تغطية CSS عبر مصفوفة من 41 حالة، مع فحص كل محدد مقابل fixture يملك مجموعة إجابات صحيحة معروفة، بالإضافة إلى جولة متعمدة للبحث عن الأعطال بهدف كسر محرك Lexbor. كل حالة نُفذت في عملية فرعية مستقلة، واتضح أن هذا كان ضروريًا — لأن إحدى الحالات كانت ستطيح بالمفسر بالكامل. والنتائج:

مقارنة تغطية محددات CSS: soupsieve ينجح في 41/41، وLexbor في 39/41

المحركنجاحخطأغير مدعومإيقاف العملية
soupsieve41000
selectolax Lexbor39020
lxml (cssselect)37130
parsel (cssselect)37130
selectolax Modest35321

عندما تدخل المحددات العدائية في الاختبار، لا يكون Lexbor هو الفائز المطلق — بل soupsieve هو الفائز، بنتيجة نظيفة 41/41 مقابل 39/41 لـ Lexbor. فشل Lexbor الوحيدين هما :lang(en) و:dir(rtl)، لأنه يرفضهما بخطأ في التحليل. وهو مثالي في كل شيء تقريبًا، بما في ذلك :has() و:is() و:where() والسمات غير الحساسة لحالة الأحرف.

لكن الشيء الذي يتألق فيه Lexbor فعلًا هو مقارنةً بطبقة cssselect. المحدد الأشهر في README — div > :nth-child(2n+1):not(:has(a)) — يرجع بالمجموعة الصحيحة على كلا محركي selectolax وعلى soupsieve، لكنه يرجع بالمجموعة الخاطئة على lxml وparsel، من دون رفع أي خطأ. يعني أداة scraping التي تنسخ هذا المحدد إلى Scrapy أو parsel ستعطيك نتائج خاطئة بصمت. وللدقة: cssselect يدعم :has() منذ الإصدار 1.2.0 (2022)، وقد اختبرت النسخة 1.4.0، لذلك المشكلة هنا هي "مدعوم لكنه يقيّمه خطأً في التركيب المركب"، وليس "غير مدعوم". هذا السلوك الخاطئ الصامت في هذا التركيب تحديدًا غير موثق في متعقب cssselect، الذي يذكر حدود :has() كأخطاء تُرفع. كما أن Lexbor يتعامل مع وسم السمة غير الحساسة [data-role="LEAD" i] الذي يرفضه cssselect رفضًا صريحًا.

لكن هناك فجوتين ستحددان قرارات الهجرة. selectolax لا يدعم XPath إطلاقًا — فلا أي من البنيتين الخلفيتين يوفّر xpath() — كما أنه لا يدعم عناصر pseudo مثل ::text و::attr()، لأنها امتداد خاص بـ parsel/Scrapy وليست CSS حقيقية. إذا كانت أدوات الاستخراج الحالية تعتمد على XPath، فهذه هي الجدار الأكبر الذي ستصطدم به؛ ستحتاج إلى إعادة كتابة المحددات، لا مجرد استبدال مكتبة بأخرى. ومن ناحية ثانية، يوفّر Lexbor pseudo-class باسم :lexbor-contains("text" i) لمطابقة النصوص بدون حساسية لحالة الأحرف، وهو شيء لا يقدمه lxml ولا parsel ولا CSS القياسية، ويعمل كما هو موضح.

المتانة مع HTML الرديء، وهنا يكسب selectolax نقاطه

الـ scraping الحقيقي يعني أنك تضع محللًا أمام مدخلات فوضوية وتأمل ألا ينهار. اختبرت 18 مدخلاً عدائيًا، وهنا تظهر حجة selectolax ضد lxml بشكل أقوى.

إذا أعطيت lxml.html.fromstring سلسلة فارغة أو مجرد مسافات، فإنه يرمي ParserError("Document is empty"). أما محركا selectolax كلاهما فيرجعان شجرة فارغة صالحة بدلًا من ذلك. بالنسبة لمتتبع بيانات يمر على قائمة روابط وتطلع بعض الردود فاضية، فهذا يعني try/except أقل حول كل شيء. كما تعامل selectolax مع 100,000 عنصر من دون أي تجاوز للمكدس.

والتداخل العميق كان الفاصل الأوضح. عند 1,000 و5,000 مستوى من <div> المتداخلة، يقوم lxml بحذف المحتوى الأعمق بصمت بينما يحتفظ به selectolax. إن libxml2 يضع حدًا لعمق التحليل عند نحو 256 مستوى ويقص الشجرة من دون أي خطأ، وبالتالي يصبح النص الأعمق غير قابل للوصول ببساطة. أما محركا selectolax فيرجعان الشجرة كاملة. وهذه صورة معاكسة لفخ <template> الذي سأذكره لاحقًا: هناك Lexbor يترك محتوى يحتفظ به الآخرون؛ وهنا lxml يحذف محتوى يحتفظ به selectolax.

ولم تكن كل الخانات انتصارًا. فمحرك Modest يقفل مفسّر Python بالكامل عبر SIGABRT عندما يواجه :dir() — وليس استثناءً يمكن التقاطه، بل إيقافًا قاسيًا للعملية. وهذه ملاحظة متانة حقيقية لأي شخص ما زال يستخدم المحرك القديم، ومن النوع الذي ما يبان إلا لما تسقط مهمة إنتاجية عند الثالثة صباحًا.

فخّان لفقد البيانات بصمت لازم تعرفهما قبل النشر

لا واحد منهما جديد — كلاهما موثق في المصدر — لكن الاثنين يكلّفان بيانات حقيقية بصمت، وما يطلعون بوضوح في README.

Lexbor لا يلتقط روابط <a> داخل <template>

على صفحة MDN الحية التي اختبرتها، وجد selectolax-Lexbor 497 رابطًا بينما وجد lxml وكلا محركي BeautifulSoup وحتى محرك selectolax Modest نفسه 508. وكانت الروابط الأحد عشر المفقودة عبارة عن مبدّل لغة ورابط نقاشات داخل عناصر <template> (والصفحة تستخدم مكونات Lit web components).

فخ template في selectolax Lexbor: 497 رابطًا مقابل 508 رابطًا

السبب هنا مشروع: بحسب مواصفة HTML5، يُحلل محتوى <template> في جزء منفصل غير فعال، وليس داخل DOM العادي، وLexbor يلتزم بهذا بدقة — لذلك tree.css("a") ما ينزل إلى محتوى template. أما lxml وكلا محركي BeautifulSoup وModest فيسطحون محتوى template داخل الشجرة الرئيسية، ولذلك يجدون تلك الروابط. وهذه مشكلة مفتوحة موثقة (selectolax#146، مع الجذر في المحرك نفسه lexbor#170)، ويمكن الدفاع عن السلوكين — فربما يكون Lexbor هو الأكثر اتساقًا مع المواصفة. لكن المطور الذي يستخدم المحرك "الموصى به" قد يفوّت هذه البيانات بصمت، من دون أي خطأ. ويستحق نقول العكس أيضًا: المحللات الأخرى قد تكشف محتوى template الخامل الذي ما يعرضه المتصفح أصلًا، وبالتالي قد تعطيك بيانات شبحية ما يشوفها المستخدم. والملاذ الأكثر موثوقية هنا هو محرك Modest، أو مكتبة ثانية، لتلك الصفحة تحديدًا.

البايتات غير UTF-8 تفسد .text() بصمت

إذا مررت إلى selectolax بايتات ليست UTF-8 صالحة، فسيتم التحليل بنجاح — لكن الفساد يظهر لاحقًا، والأسوأ أنه يحدث بشكل أخفى من الانهيار الواضح. عند "<p>café éè</p>".encode("latin-1")، تعيد .text() في Lexbor أحرف استبدال، بينما تحذف .text() في Modest البايتات المسببة للمشكلة بصمت، ولا يرمي المحركان UnicodeDecodeError إلا عندما تلمس .html. فك الترميز يحصل عند القراءة اللاحقة بصورة UTF-8 صارمة، وليس عند التحليل. وهذا مرتبط بمشكلة معروفة في selectolax حول صرامة الترميز/فك الترميز selectolax issue.

والحل سطر واحد ولازم يصير عادة تلقائية: فك ترميز البايتات بنفسك أولًا — LexborHTMLParser(resp.content.decode("latin-1")) — وبعدها يعيد المحركان 'café éè' بشكل صحيح. عمليًا، أعطِ selectolax دائمًا str، وليس bytes خام غير UTF-8. الـ README ما يشرح هذا بوضوح.

أبعاد الإنتاج في الواقع العملي (قياس واحد فقط، لذا اعتبرها مؤشرات لا أرقام نهائية)

النتائج التالية قستها مرة واحدة فقط، لا ثلاث مرات، لذلك أقدمها كإشارات لا كأرقام محسومة.

القياس المتعلق بالتوسع مع الخيوط هو الأهم. عند تحليل صفحة بحجم 1 MB لعدد 48 مرة عبر أربع خيوط، أظهر selectolax تسريعًا زمنيًا حقيقيًا بنحو 3.5-3.9 مرة — وهذا هو التوقيع التجريبي لمكتبة تحرر GIL أثناء التحليل بـ C — بينما أصبح BeautifulSoup(lxml) أبطأ بعدة مرات عند التشغيل متعدد الخيوط، وهو توقيع لعمل يتسلسل بسبب GIL. وجاء lxml في المنتصف من دون نتيجة حاسمة. بالنسبة لعصر free-threading الذي تتجه إليه Python، فإن selectolax الذي يوازي العمل عبر الخيوط بينما BeautifulSoup لا يفعل ذلك، يعتبر ميزة حقيقية، ولو كانت أولية. هذا القياس بمتغير واحد وعلى حجم صفحة واحد، والآلية هنا مجرد فرضية لا شيء أثبته بفحص كود C نفسه.

أما التسريبات: على مدى 2,000 دورة من التحليل-الاستخراج-الإسقاط عند حجم 1 MB، لم يُظهر أي من المحللات الثلاثة صعودًا خطيًا في RSS يشير إلى تسريب — بل استقر كل واحد ضمن نطاق محدود. وأنا واثق من هذه النتيجة تحديدًا لأنني مررت حالة معايرة معروفة بالتسريب عبر الأداة نفسها، فصعدت إلى +198 MB كما هو متوقع، ما يثبت أن الأداة قادرة على رؤية التسريب، لكنها لم تجد واحدًا في هذه المحللات. كما أن مقبض عقدة بقي حيًا بعد خروج الشجرة المالكة له من النطاق، وظل قابلًا للاستخدام من دون segfault. لكن كلها ملاحظات من قياس واحد، لا اختبارات طويلة تمتد لساعات.

أين يناسب selectolax — وأين يسلّم المهمة لغيره

كل ما سبق يتعلق بمهمة واحدة: تحويل HTML الذي تملكه مسبقًا إلى بيانات منظمة، وبسرعة. وselectolax ممتاز في هذه المهمة. لكنه لا يقوم بما لا يريد القيام به: جلب الصفحة، أو تنفيذ JavaScript، أو تدوير البروكسيات، أو حل CAPTCHA، أو تحديد العناصر التي تريدها. كل ذلك ما زال على عاتقك. selectolax هو طبقة التحليل، ولا يدّعي أكثر من ذلك.

وهنا تأتي النقطة التي تقف عندها خدمة استخراج مُدارة فوق المحلل بدلًا من أن تستبدله. إذا كنت تفضّل عدم بناء وصيانة سلسلة fetch-render-anti-bot-extract بنفسك، فإن Thunderbit يوفّر ذلك عبر API، وخادم MCP، وCLI — حيث يحول POST /distill الصفحة إلى Markdown نظيف، بينما يعيد POST /extract JSON منظمًا مطابقًا للهيكل المطلوب، مع معالجة عرض JavaScript والحماية من الروبوتات نيابةً عنك. إنها طبقة مختلفة من المشكلة: تستخدم selectolax عندما تكون لديك HTML أصلًا وتريد سرعة تحليل خامة تحت سيطرتك، وتستخدم شيئًا مثل API أو خادم MCP أو CLI من Thunderbit عندما تريد أن تُدار عملية الجلب والاستخراج وتستلم فقط بيانات منظمة. ليس استبدالًا، بل طبقة ثانية في نفس السلسلة.

جرّب Thunderbit لاستخراج بيانات الويب

الإيجابيات والسلبيات ومن يجب أن يستخدمه فعلًا

أين يفوز selectolax:

  • أسرع بنحو 12-17 مرة من BeautifulSoup في أعمال التحليل والاستخراج الواقعية، وبثبات عبر ثلاث مراتب من أحجام الصفحات.
  • ذاكرة خفيفة (ضمن طبقة lxml، وأخف بنحو 1.5-1.8 مرة من BeautifulSoup) مع زمن استيراد يقارب 14 ms.
  • متسامح مع المدخلات التي تكسر lxml — مثل السلاسل الفارغة، والمسافات، والتداخل العميق جدًا.
  • CSS حديث يشمل :has() و:is() و:where()، والسمات غير الحساسة لحالة الأحرف، و:lexbor-contains() الخاص بـ Lexbor.
  • DOM للقراءة/الكتابة آمن مع None: العناصر المفقودة تعود بـ None أو [] بدلًا من رمي الاستثناءات، ويمكنك تعديل الشجرة وإعادة تسلسلها فعليًا.
  • صيانة نشطة (v0.4.10، منتصف 2026) وتثبيت سهل جدًا.

أين لا يفوز:

  • ليس أسرع بوضوح من lxml — تعادل في المهمة الكاملة، وخسر مرحلة التحليل البحت في هذا القياس.
  • لا يدعم XPath ولا ::text/::attr() — وهي عقبة هجرة كبيرة لمن يعتمد على XPath.
  • فخّان لفقد البيانات بصمت: محتوى <template> على Lexbor، وبايتات غير UTF-8 عبر .text().
  • محرك Modest قديم ويفشل بإيقاف قاسٍ عند :dir().
  • كل رقم هنا خاص بمنصة واحدة (macOS arm64، Python 3.14) وأولي.

هل تستخدم selectolax؟ نعم، إذا كنت تريد سرعة تحليل بمستوى lxml مع واجهة أرحم وأمان أفضل مع None، وسلوكًا أفضل بكثير مع المدخلات الفارغة أو المشوّهة — وإذا كنت مرتاحًا للبقاء داخل عالم CSS فقط. أما إذا كان مشروعك مبنيًا على XPath، فتكلفة إعادة الكتابة حقيقية ولازم تنحسب بصدق. وإذا كنت تبحث عن "المحلل الأسرع الوحيد"، فالجواب الدقيق من هذا القياس هو أن selectolax وlxml متقاربان إلى درجة أن عامل الحسم هو سهولة الاستخدام والمتانة، لا السرعة الخام. وهذه أصلًا سبب أفضل لاختيار أداة.

جرّب Thunderbit لاستخراج بيانات الويب Get Started Free

الأسئلة الشائعة

هل selectolax أسرع من BeautifulSoup؟ نعم، وبوضوح — أسرع بنحو 12-17 مرة من BeautifulSoup(html.parser) وأسرع بنحو 10-14 مرة من BeautifulSoup(lxml) في مهمة تحليل واستخراج واقعية، مع ثبات النتائج من صفحات 1 KB حتى 10 MB (macOS arm64، Python 3.14). الرقم الشائع "4-5 مرات" يقلل الفارق مع html.parser.

هل selectolax أسرع من lxml؟ ليس بشكل عام. في مهمة التحليل والاستخراج الكاملة يتعادل الاثنان عند 100 KB و1 MB، ولا يفوز selectolax إلا في صفحة 10 MB. أما في التحليل البحت من دون استعلام، فكان lxml أسرع بنحو 33-34% على جهازي — وهي نتيجة مخالفة للتوقعات، لذلك أتعامل معها على أنها خاصة بمنصة واحدة وتستحق التحقق على عتادك.

هل أستخدم محرك Lexbor أم Modest؟ Lexbor، في معظم الحالات — فهو المحرك الذي ما زال قيد الصيانة وكامل الميزات، والمُوصى به في README، مع تغطية CSS أفضل. الاستثناء الوحيد هو الصفحة التي تخفي محتوى داخل عناصر <template>، حيث يتصرف Lexbor وفق المواصفة ويترك هذا المحتوى، بينما يحتفظ به Modest بالمصادفة. لكن Modest أيضًا عنده حواف حادة، منها انهيار قاسٍ للمفسر عند :dir().

هل يدعم selectolax XPath؟ لا. لا أي من البنيتين الخلفيتين يوفّر xpath() — selectolax يعمل فقط عبر CSS. إذا كانت أدوات الاستخراج عندك تعتمد على XPath، فالهجرة تعني إعادة كتابة المحددات، وهذه هي الكلفة الأكبر عند الانتقال من بنية مبنية على lxml أو parsel إلى selectolax.

لماذا يبدو إخراج selectolax مشوهًا أو يفتقد بعض العناصر؟ غالبًا أحد سببين. إذا رجعت النصوص بأحرف بديلة أو اختفت اللكنات، فغالبًا أنك مررت بايتات خام غير UTF-8 — فك ترميزها إلى str أولًا (resp.content.decode("latin-1")) قبل التحليل. وإذا كانت الروابط أو العناصر مفقودة في موقع حديث، فقد تكون داخل وسوم <template> التي لا ينزل إليها محرك Lexbor؛ بدّل إلى Modest أو استخدم محللًا آخر لتلك الصفحة.

Ke
Ke
المدير التقني في Thunderbit | عالم بيانات أول وخبير في تعلّم الآلة بخبرة تقارب عقدًا من الزمن في تعلّم الآلة وعلم البيانات، كيه شين خريج جامعة كولومبيا وكان سابقًا عالم بيانات أول في Walmart Labs. وبفضل خبرته العميقة المعترف بها من قبل الأقران في Python وR وJava والإحصاء، يشارك رؤى مجرّبة حول نقل خوارزميات الذكاء الاصطناعي المعقدة من النظرية إلى بنية جاهزة للإنتاج.
Topics
أدوات استخراج البيانات من الويبAI Web Scraper

جرّب Thunderbit

استخرج العملاء المحتملين وبيانات أخرى في خطوتين فقط. مدعوم بالذكاء الاصطناعي.

احصل على Thunderbit مجاني
استخرج البيانات باستخدام الذكاء الاصطناعي
انقل البيانات بسهولة إلى Google Sheets أو Airtable أو Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week