PyQuery يضيف صياغة jQuery دون أي عبء اختيار مؤثر على القرار في هذا الاختبار

آخر تحديث في August 18, 2026
PyQuery يضيف صياغة jQuery دون أي عبء اختيار مؤثر على القرار في هذا الاختبار
ملخص الذكاء الاصطناعي
يضع PyQuery واجهة على نمط jQuery فوق lxml. وعلى امتداد خمس أحجام صفحات من 1 KB إلى 10 MB، كانت جميع الوسيطات المعروضة أقل من lxml الخام، بما في ذلك فرق بنسبة 1.5% عند أكبر حجم. لا يثبت الاختبار أن الغلاف أسرع؛ بل لم يجد فرقًا كبيرًا بما يكفي لتغيير قرار الاختيار والقراءة هذا. كما كان قريبًا ضمن بضعة في المئة من selectolax ابتداءً من 10 KB في الوسيطات المعروضة. ومن دون هامش تكافؤ محدد مسبقًا، تُعد هذه نتيجة متقاربة لا تعادلًا إحصائيًا.

يضع PyQuery واجهة تشبه jQuery فوق lxml. وعلى امتداد خمس أحجام صفحات من 1 KB إلى 10 MB، كانت جميع الوسيطات الظاهرة أقل من lxml الخام، بما في ذلك فرق بنسبة 1.5% عند أكبر حجم. هذا الاختبار لا يثبت أن الغلاف أسرع؛ بل فقط لم يجد فرقًا كبيرًا بما يكفي ليغيّر قرار الاختيار والقراءة هنا.

كما أنه كان قريبًا ضمن بضعة في المئة من selectolax ابتداءً من 10 KB في الوسيطات المعروضة. ومن دون هامش تكافؤ محدد مسبقًا، تُعد هذه نتيجة متقاربة لا تعادلًا إحصائيًا.

ما هو PyQuery

PyQuery هي مكتبة Python تمنحك واجهة اختيار وتسلسل على نمط jQuery فوق شجرة مستندات lxml. الإصدار المختبَر: 2.1.0، بترخيص BSD، 2,380 نجمة على GitHub، و59 مشكلة مفتوحة، وآخر دفع بتاريخ 2026-07-27.

المرجع الرسمي: وثائق PyQuery.

System diagram: jQuery Syntax Over lxml

from pyquery import PyQuery as pq
d = pq(html)
titles = [e.text_content() for e in d("h3.title")]
hrefs = [e.get("href") for e in d("a")]

العناصر التي يعيدها هي عناصر lxml، لذا فكل ما تعرف كيف تفعله مع lxml سيظل يعمل. هذه هي الفكرة الأساسية: PyQuery طبقة تحسين تجربة استخدام، وليس محللًا بحد ذاته. أمر pip install pyquery يجلب 3 حزم — lxml وcssselect وPyQuery نفسه — و20.1 MiB، ومعظمها يعود إلى الامتدادات المجمعة الخاصة بـ lxml.

إذا كنت قد استخدمت cheerio في Node، فهذه هي الفكرة العامة نفسها ولكن في Python. وقد عمل المنتجان اللذان جرى اختبارهما هنا ضمن كلاهما؛ إلا أن هذا الاختبار لا يثبت تكافؤ لغة الاختيار بين cssselect وcheerio.

المنهجية

كانت قاعدة الأبحاث هذه تحتوي بالفعل على اختبار أداء للمحللات يتميز بميزة نادرة في أغلب الاختبارات: بوابة تكافؤ تتحقق عبر تجزئة المحتوى المستخرج — عناوين مرتبة بالإضافة إلى روابط href مرتبة — مقارنةً بمحلل مرجعي، بحيث لا تستطيع مكتبة تتجنب العمل أن تسجل زمنًا سريعًا بشكل مضلل. خمسة أحجام صفحات، 50 تكرارًا، وثلاث تشغيلات مستقلة.

إضافة PyQuery إلى هذا الإطار تطلب أمرين.

إعادة تشغيل المرجع. أُعيد تشغيل selectolax في العملية نفسها. وتكررت تجزئة المحتوى بنجاح على 5 من 5 أحجام، وجاءت p50 بين 0.989× و1.079× من القيمة المنشورة — وهذا يعني أنها على نفس الجهاز ونفس بيئة الاختبار.

تشغيل lxml في العملية نفسها أيضًا. يسجل الاختبار المنشور الجهاز وإصدار Python، لكنه لا يسجل إصدارات المكتبات، لذا ربما جاءت صف lxml من إصدار مختلف عن lxml الذي يغلّفه PyQuery هنا. المقارنة عبر هذه الفجوة كانت ستقارن إصدارين مختلفين من lxml وتصف ذلك على أنه كلفة الغلاف. تشغيل lxml إلى جانب PyQuery يزيل هذا الالتباس — فكلاهما lxml 6.1.1 في هذه البيئة الافتراضية.

حجم الصفحةselectolaxPyQuerylxmlPyQuery مقابل lxml
1 KB0.0286 ms0.0456 ms0.0508 ms0.90×
10 KB0.1725 ms0.1728 ms0.1802 ms0.96×
100 KB1.4855 ms1.4093 ms1.4145 ms1.00×
1 MB14.97 ms14.96 ms15.03 ms1.00×
10 MB158.10 ms162.86 ms165.25 ms0.99×

القيم المعروضة هي p50 بالمللي ثانية، أي وسيط ثلاث تشغيلات، كلها في عملية واحدة. parser-bench.json. تطابقت جميع تجزئات المحتوى الثلاث مع المرجع في كل حجم.

عبء الغلاف الذي لم يظهر

Measured results chart: PyQuery and lxml on the same fixture

جاء PyQuery عند أو أقل من lxml الخام في كل وسيط ظاهر. وهذا لا يُعد دليلًا على أن الغلاف يجعل التحليل أسرع. ثلاث وسيطات تشغيل وعدم وجود هامش تكافؤ محدد مسبقًا يدعمان الاستنتاج الأضيق بأن هذه العينة لم تُظهر عبئًا في الاختيار مؤثرًا على القرار.

عند 10 MB، كانت تشغيلات PyQuery الثلاث 162.86 و163.17 و161.13 ms؛ وكانت تشغيلات lxml 169.46 و165.25 و164.18. النطاقات متقاربة لكن لا تتداخل. وعند 1 MB يختلف الوسيطان بنسبة 0.5% فقط. هذه التشغيلات الصغيرة تدعم حكمًا عمليًا، لا ادعاء تكافؤ إحصائيًا.

System diagram: Wrapper and Parser Boundaries

الآلية بسيطة بما يكفي: pq(html) يبني شجرة lxml مرة واحدة، وd("h3.title") يترجم محدد CSS عبر cssselect كما تفعل tree.cssselect()، والعناصر المعادة هي عناصر lxml. لذلك فهناك عمل قليل نسبيًا من PyQuery في هذا المسار الساخن المقاس. أما التنقل، والتعديل، والاستعلامات المتكررة، والاستيراد، واستهلاك الذاكرة فكلها خارج نطاق الادعاء الخاص بزمن الاختيار.

نتائج متقاربة ابتداءً من 10 KB

النتيجة الأكثر فائدة تظهر في العمود الأول.

ابتداءً من 10 KB، كان الفرق بين الأسرع والأبطأ في الوسيطات بين selectolax وlxml وPyQuery هو 4.5% عند 10 KB، و5.4% عند 100 KB، و0.5% عند 1 MB، و4.5% عند 10 MB. لم يكن هذا التشغيل اختبار تكافؤ؛ والاستنتاج العملي هو أن هذه الفجوات لن تغيّر غالبًا قرار اختيار المحلل لهذا الحمل.

selectolax أسرع فعلًا عند 1 KB — 0.0286 ms مقابل 0.0456 و0.0508 — لكن هذا الصف غير صالح للحكم. فالفارق بين المحللات الثلاثة عند هذا الحجم هو 77.6%، كما أن تشغيلات selectolax نفسها تراوحت بين 0.0267 و0.0404 ms. عند 28 ميكروثانية يهيمن المؤقت وجدول المهام على القياس. لا يمكنني ترتيب أي شيء هناك.

في هذا الحمل القائم على الاختيار والقراءة، اختر بين هذه الخيارات الثلاثة بناءً على واجهة الاستخدام والحقائق المقاسة الخاصة بالاعتمادات، لا على افتراض تسلسل سرعة مسبق. أظهر PyQuery عدم وجود كلفة مؤثرة على القرار مقارنةً بـ lxml. أما selectolax فيستخدم حزمة محلل مختلفة، لكن هذه المقالة لم تقس بصمته المثبتة أو تغطية الحزمة أو متطلبات البناء على الأساس نفسه.

ولأغراض المقارنة، وضع الاختبار المنشور خيارين إضافيين في Python على نفس عينة 10 MB، وهما اللذان يختلفان فعلًا:

المحلل (10 MB)p50
selectolax (lexbor)159.93 ms
lxml172.93 ms
parsel231.85 ms
selectolax (modest)247.95 ms
BeautifulSoup + lxml2,261.56 ms
BeautifulSoup + html.parser2,788.75 ms

القيم المنشورة مأخوذة من bench_parse.json.

تُظهر صفوف الاختبار التاريخية أن BeautifulSoup يتجاوز المحللات الأسرع في هذه العينة بأكثر من رتبة مقدار. ولم تُعد هذه الصفوف التشغيل مع زوج PyQuery/lxml في العملية الحالية، لذا فهي سياق مفيد لا مضاعف مضبوط للحكم الأساسي.

وكان الصف المخزن الخاص بـ cheerio هو 2,927.89 ms (2927.8857 في parser-bench.json) مع تطابق تجزئات المحتوى المستخرج. هذه النتيجة عبر بيئتين تشغيلية تعتمد أيضًا على Node وإصدارات الحزم وضوابط التشغيل التاريخية؛ ولا ينبغي قراءتها على أنها مضاعف سرعة لمكتبة منفردة.

واقع الإعداد

المكتبةالحزمالحجم على القرصالترخيصالنجومآخر دفع
PyQuery320.1 MiBBSD2,3802026-07-27
cheerio (Node)22 (npm)9.0 MiBMIT30,4492026-08-11

المرجع الرسمي: PyQuery على PyPI.

metadata-snapshot.json.

ثلاث حزم تعني بصمة اعتماد بسيطة ومنظمة، واثنتان منها — lxml وcssselect — موجودتان أصلًا في كثير من مشاريع استخراج البيانات في Python. في هذه الحالة تكون الكلفة الهامشية لـ PyQuery بضع عشرات من الكيلوبايت.

أما 20.1 MiB فهي امتدادات lxml المجمعة، وليست PyQuery. وهي نفسها تقريبًا الكلفة التي تدفعها إذا استخدمت lxml مباشرة.

المكتبة مرخصة بترخيص BSD. وفي اللقطة المؤرخة كان لديها 59 مشكلة مفتوحة ودفع تم قبل ثلاثة أسابيع من الاختبار؛ وهذه الملاحظات وحدها لا تثبت جودة الصيانة أو التوافق المستقبلي.

الذاكرة، وما الذي يفعله HTML المعطوب بها

شيئان ذكرتهما كل مراجعة في هذه المجموعة على أنهما غير مختبرين، وقد جرى قياسهما الآن.

سياق اختبار التحمل الأوسع موجود في مقارنة الذاكرة وHTML المعطوب عبر عشر مكتبات.

الذروة في الذاكرة المقيمة، عبر /usr/bin/time -l، مع عملية جديدة لكل خلية — الحد الأدنى عند الاستيراد هو ما تستهلكه المكتبة وهي محمّلة وخاملة، أما الذروات فتشمل المستند.

المكتبةوقت التشغيلحد الاستيراد الأدنىذروة 226 KBذروة 10 MB
html2textpython3.1418.719.971.2
pyquerypython3.1430.333.9172.5
resiliparsepython3.1420.525.1225.1
markdownifypython3.1423.928.9278.5
goose3python3.1444.152.4398.5
cheerionode2266.876.5398.5
justextpython3.1430.336.6431.2
newspaper4kpython3.1452.661.8668.5
trafilaturapython3.1452.564.8927.1
turndownnode2247.868.42947.1

memory-results.json. لا يمكن مقارنة خط الأساس في Python بخط الأساس في Node مباشرة؛ فالمفسر نفسه جزء من القياس في كليهما.

PyQuery أخف من resiliparse على المستند الكبير — 172.5 MiB مقابل 225.1 — رغم أن حد الاستيراد الأدنى أعلى قليلًا. شجرة lxml مدمجة، ومعظم حد 30.3 MiB في PyQuery يعود إلى تحميل lxml نفسه لا إلى ما يفعله PyQuery.

HTML المعطوب. اثنا عشر مستندًا، كل واحد منها يكسر شيئًا واحدًا فقط — وسوم غير مغلقة، عناصر inline غير متداخلة بشكل صحيح، سمات غير مقتبسة فيها مسافات، وسوم إغلاق شاردة، عدم وجود <html> أصلًا، سمات مكررة، مستند مقطوع في منتصف الوسم، كيانات سيئة، <script> غير مغلق، إعلان charset مضلل، تعليق يحتوي على ترميز HTML، و600 مستوى من التعشيق — بالإضافة إلى عيني تحكم سليمتين عند أحجام متطابقة، لأن عبارة "لم يُرجع شيئًا" لا تقول شيئًا عن فساد البنية إذا كانت المكتبة صامتة أيضًا على مستند سليم بنفس الحجم.

لم يرمِ pyquery استثناءً في 0 من 14 ولم يُرجع شيئًا في 1، واستعاد 10/22 من العلامات المرجعية عبر العينات المعطوبة (malformed-results.json). وهناك عينة مستبعدة من هذا العد: وفق HTML5، كل ما بعد <script> غير المغلق هو محتوى script بالفعل، لذا فإن فقدانه هناك صحيح، بينما استعادته هو الانحراف. ومن دون نتائج العلامات المرجعية للبدائل المباشرة بجانبه، فإن 10/22 تبقى ملاحظة متانة لا ترتيبًا لاختيار محلل.

الإيجابيات والسلبيات

ما له. صياغة jQuery مألوفة لأي شخص كتب JavaScript للواجهة الأمامية أو استخدم cheerio. لم يظهر أي عبء في الاختيار مؤثر على القرار مقارنةً بـ lxml الخام في هذه العينة. ثلاث حزم فقط، واثنتان منها موجودتان على الأغلب بالفعل في مشروعك. يعيد عناصر lxml، لذا تبقى تقنيات lxml متاحة. BSD. وتطابقت تجزئات المحتوى مع المرجع في جميع الأحجام الخمسة.

ما عليه. 20.1 MiB، بسبب lxml. و2,380 نجمة تعني مجتمعًا أصغر بكثير من cheerio ذي 30,449 نجمة — أي أمثلة عملية أقل عندما يكون هناك شيء غير مألوف. وهي طبقة راحة، لذا فما لا يستطيع lxml فعله لا تستطيع هي فعله. وإذا كنت تأمل أن تمنحك واجهة jQuery أداءً أفضل، فلن يحدث ذلك: ما تمنحه هو سهولة الاستخدام، أما المحلل في الأسفل فهو من يقوم بالعمل.

من ينبغي أن يستخدمه ومن لا ينبغي

استخدم PyQuery إذا كنت أنت أو فريقك تفضلون محددات على نمط jQuery في Python. أظهر المسار المقاس الخاص بالبناء، ثم اختيارين وقراءة، عدم وجود عقوبة مؤثرة على القرار مقارنةً بـ lxml؛ ولم تُقَس عمليات PyQuery الأخرى.

استخدم lxml مباشرة إذا كنت تفضل XPath أو تريد حزمة أقل. هذا التشغيل لم يُظهر سببًا في الأداء يجعلك تختار أحدهما على الآخر.

قيّم selectolax إذا كانت واجهة محلله وبنية اعتماده تناسب مشروعك. صف 1 KB غير مصنف عمدًا، وهذه المقالة لا تدعم ادعاء "أصغر اعتماد".

في Node، cheerio هو الشكل الواجهة المناظر. كانت الصفوف المخزنة عبر البيئات أبطأ هنا، لكن اختلاف وقت التشغيل وضوابط التشغيل التاريخية يمنعان استنتاجًا نظيفًا خاصًا بالمكتبة وحدها.

أين يناسب API المُدار

PyQuery يحلل HTML الذي تملكه مسبقًا. لا يقوم بجلب الصفحة، ولا بتنفيذ JavaScript، ولا بالتعامل مع طبقة مكافحة الروبوتات — ولا أي محلل في هذه المقارنة يفعل ذلك، وفي كثير من الأهداف الواقعية يكون ذلك هو الجزء الأصعب.

ملاحظة المؤلف: Thunderbit هو خيارنا المُدار للجلب/التصيير والاستخراج من خلال عنوان URL. ولم تتم مقارنته بـ PyQuery هنا. الحد الفاصل المهم هو: هل لديك HTML بالفعل وتريد محددات محلية، أم أنك تريد عملية جلب الصفحة والاستخراج كخدمة.

الصياغة الصادقة: إذا كان لديك HTML وتعرف محدداتك، فإن PyQuery مجاني ومريح. أما إذا كانت المحددات تتعطل باستمرار، أو كنت تجلب على نطاق واسع، فهذه عملية شراء مختلفة.

ولمشهد أوسع، يغطي استعراض واجهات برمجة تطبيقات الويب لاستخراج البيانات الخيارات المستضافة، بينما يغطي دليل أدوات الاستخراج مفتوحة المصدر الأدوات ذاتية الاستضافة. وإذا كانت المخرجات المحللة ستغذي نموذجًا، فمقال تحويل HTML إلى Markdown في Python يوضح أين تضيع الدقة.

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

هل ينبغي أن تستخدم PyQuery؟

نعم، إذا كنت تريد صياغة على نمط jQuery في Python وكان مسار الاختيار والقراءة المقاس يمثل عملك.

لم يجد الاختبار عبئًا في الاختيار مؤثرًا على القرار مقارنةً بـ lxml، مع الحفاظ على تطابق تجزئة المحتوى. لكنه لم يثبت أن تكلفة المكتبة كلها تساوي الصفر.

وعبر خمسة أحجام، ظلت وسائط المحلل الثلاثة في Python متقاربة بما يكفي بحيث يصبح توافق الواجهة على الأرجح أهم من الفروق. حدد هامش تكافؤ وأعد تشغيل البدائل نفسها تمامًا قبل تحويل هذا الحكم إلى ترتيب أوسع للمحللات.

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

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

هل يبطئ PyQuery lxml؟ لم يظهر أي عبء في الاختيار مؤثر على القرار في هذا التشغيل. وعلى امتداد خمسة أحجام صفحات، جاءت وسائطه عند أو أقل من lxml الخام، وكلاهما استخدم lxml 6.1.1 في العملية نفسها. عند 10 MB لم تتداخل النطاقات المتقاربة: PyQuery بين 161.13 و163.17 ms وlxml بين 164.18 و169.46 ms. ينشئ pq(html) شجرة lxml، والمحددات المختبرة تُترجم عبر cssselect.

هل selectolax أسرع من PyQuery؟ كانت وساطته عند 1 KB أقل، لكن هذا الصف غير مصنف لأن التباين يهيمن عند مستوى الميكروثانية. ومن 10 KB فما فوق، تراوحت الفروق في الوسيطات بين 0.5% و5.4%. هذا قريب لهذا الحمل، لكنه ليس دليلاً على التكافؤ أو على تداخل النطاقات في كل الحالات.

لماذا أعدتم تشغيل lxml بدل الاكتفاء بالرقم المنشور؟ لأن الاختبار المنشور يسجل الجهاز وإصدار Python لكنه لا يسجل إصدارات المكتبات. قد تكون صف lxml فيه جاء من إصدار مختلف عن الذي يغلّفه PyQuery اليوم، وكانت فجوة الإصدار ستظهر على أنها كلفة غلاف غير موجودة. تشغيل الاثنين في عملية واحدة على lxml 6.1.1 يزيل الغموض.

كيف يقارن مع cheerio؟ الفكرة العامة للواجهة نفسها، لكن النظام البيئي مختلف. المحددان اللذان جرى اختبارهما هنا عملا في كليهما وتطابقت تجزئات المحتوى في جميع الأحجام الخمسة؛ وهذا لا يثبت توافقًا كاملًا على مستوى المحددات. كانت أزمنة cheerio المخزنة أبطأ، لكن اختلاف البيئات وضوابط التشغيل التاريخية يمنعان ادعاء مضاعف خاص بالمكتبة وحدها.

ما الذي لم يُختبر هنا؟ جرى قياس الذاكرة على أنها ذروة RSS للاستيراد فقط، ومستند 226 KB، ومستند 10 MB. أما HTML المعطوب فتمت تجربته عبر 12 مستندًا مكسورًا مع عيني تحكم متطابقتين. وما يزال غير مختبر: أداء التعديل والتنقل في PyQuery، والتخزين المؤقت للاستعلامات المتكررة، وجلب الروابط، والتزامن، وأحمال مواقع حقيقية ممثلة. ويبقى توقيت 1 KB غير مصنف.

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

استخرج البيانات من أي صفحة في بنقرة واحدة

يثق به أكثر من 250,000 مستخدم
تتوفر خطة مجانية
من صفحة ويب إلى جدول بيانات
صف ما تحتاجه — يتولى وكيل Thunderbit الذكي استخراجه وتصديره إلى Excel أو Google Sheets أو Airtable أو Notion. ابدأ مجانًا.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week