تريد المساعدة؟ إليك خياراتك:","كرانش بيس","نبذة عنا","شكراً للجميع على الدعم الرائع!","روابط سريعة","برنامج الإحالة","بريميوم","ProxyScrape تجربة متميزة","مدقق الوكلاء عبر الإنترنت","أنواع الوكلاء","الدول الوكيلة","حالات استخدام الوكيل","مهم","سياسة ملفات تعريف الارتباط","إخلاء المسؤولية","سياسة الخصوصية","الشروط والأحكام","وسائل التواصل الاجتماعي","فيسبوك","لينكد إن","تويتر","كورا","برقية","الخلاف","\n © حقوق الطبع والنشر © 2024 - ثيب بي في | بروغسترات 18 | 2812 ميكلين | بلجيكا | ضريبة القيمة المضافة BE 0749 716 760\n"]}
عندما يتعلق الأمر بالتزامن مقابل التوازي، قد يكون من الواضح أنهما يشيران إلى نفس المفاهيم في تنفيذ برامج الكمبيوتر في بيئة متعددة الخيوط. حسنًا، بعد النظر إلى تعريفاتهما في قاموس أكسفورد، قد تميل إلى الاعتقاد بذلك. ومع ذلك، عندما تتعمق أكثر في هذه المفاهيم فيما يتعلق بـ
عندما يتعلق الأمر بالتزامن مقابل التوازي، قد يكون من الواضح أنهما يشيران إلى نفس المفاهيم في تنفيذ برامج الكمبيوتر في بيئة متعددة الخيوط. حسنًا، بعد النظر إلى تعريفاتهما في قاموس أكسفورد، قد تميل إلى الاعتقاد بذلك. ومع ذلك، عندما تتعمق أكثر في هذه المفاهيم فيما يتعلق بكيفية تنفيذ وحدة المعالجة المركزية لتعليمات البرنامج، ستلاحظ أن التزامن والتوازي هما مفهومان مختلفان.
تتعمق هذه المقالة في هذه المقالة في التزامن والتوازي وكيفية اختلافهما وكيفية عملهما معًا لتحسين إنتاجية تنفيذ البرامج. وأخيراً، سيناقش أي الاستراتيجيتين هما الأكثر ملاءمة لكشط الويب. لذا دعونا نبدأ.
أولاً، لتبسيط الأمور، سنبدأ بالتزامن في تطبيق واحد يتم تنفيذه في معالج واحد. يعرّف قاموس Dictionary.com التزامن على أنه عمل أو جهد مشترك ووقوع أحداث متزامنة. ومع ذلك، يمكن للمرء أن يقول الشيء نفسه عن التنفيذ المتوازي حيث تتزامن عمليات التنفيذ، وبالتالي فإن هذا التعريف مضلل إلى حد ما في عالم برمجة الكمبيوتر.
في الحياة اليومية، سيكون لديك عمليات تنفيذ متزامنة على جهاز الكمبيوتر الخاص بك. على سبيل المثال، قد تقرأ مقالة مدونة على متصفحك أثناء الاستماع إلى الموسيقى على مشغل وسائط Windows Media Player. قد تكون هناك عملية أخرى قيد التشغيل: تنزيل ملف PDF من صفحة ويب أخرى - كل هذه الأمثلة هي عمليات منفصلة.
قبل اختراع التطبيقات ذات التنفيذ المتزامن، كانت وحدات المعالجة المركزية تنفذ البرامج بالتتابع. وكان هذا يعني أن تعليمات أحد البرامج يجب أن تكتمل في التنفيذ قبل أن تنتقل وحدة المعالجة المركزية إلى البرنامج التالي.
في المقابل، يقوم التنفيذ المتزامن بتبديل جزء صغير من كل عملية حتى تكتمل جميعها.
في بيئة التنفيذ متعدد الخيوط ذات المعالج الواحد، يتم تنفيذ برنامج واحد عندما يتم حظر برنامج آخر لإدخال المستخدم. قد تسأل الآن ما هي بيئة التنفيذ متعدد الخيوط. إنها مجموعة من الخيوط التي تعمل بشكل مستقل عن بعضها البعض - المزيد عن الخيوط في القسم التالي.
والآن، من السهل الخلط بين التزامن والتوازي. ما قصدناه بالتزامن في الأمثلة أعلاه هو أن العمليات لا تعمل بشكل متوازي.
وبدلاً من ذلك، لنفترض أن إحدى العمليات تتطلب إكمال عملية إدخال/إخراج، فإن نظام التشغيل سيخصص وحدة المعالجة المركزية لعملية أخرى أثناء إكمال عملية الإدخال/الإخراج الخاصة بها. سيستمر هذا الإجراء حتى تكمل جميع العمليات تنفيذها.
ومع ذلك، نظرًا لأن تبديل المهام من قبل نظام التشغيل يحدث في غضون نانو أو ميكروثانية، فسيظهر للمستخدم أن العمليات يتم تنفيذها بشكل متوازٍ,
على عكس التنفيذ المتسلسل، قد لا تقوم وحدة المعالجة المركزية بتنفيذ العملية/البرنامج بأكمله دفعة واحدة مع البنى الحالية. بدلاً من ذلك، قد تقوم معظم الحواسيب بتقسيم العملية بأكملها إلى عدة مكونات خفيفة الوزن تعمل بشكل مستقل عن بعضها البعض بترتيب عشوائي. هذه المكونات خفيفة الوزن هي التي تسمى خيوط.
على سبيل المثال، قد يحتوي محرر مستندات Google على عدة سلاسل رسائل تعمل بشكل متزامن. بينما يقوم أحد الخيوط بحفظ عملك تلقائيًا، قد يعمل خيط آخر في الخلفية للتدقيق الإملائي والنحوي.
يحدد نظام التشغيل ترتيب الخيوط التي يجب تحديد أولويتها، وهو أمر يعتمد على النظام.
أنت تعرف الآن تنفيذ برامج الكمبيوتر في بيئة ذات وحدة معالجة مركزية واحدة. في المقابل، تقوم الحواسيب الحديثة بتنفيذ العديد من العمليات في وقت واحد في وحدات معالجة مركزية متعددة، وهو ما يعرف بالتنفيذ المتوازي. تحتوي معظم البنى الحالية على وحدات معالجة مركزية متعددة.
كما ترى في الرسم البياني أدناه، تقوم وحدة المعالجة المركزية بتنفيذ كل مؤشر ترابط ينتمي إلى عملية بالتوازي مع بعضها البعض.
في التوازي، يقوم نظام التشغيل بتبديل الخيوط من وحدة المعالجة المركزية وإليها في أجزاء من الماكرو أو الميكروثانية حسب بنية النظام. لكي يحقق نظام التشغيل التنفيذ المتوازي، يستخدم مبرمجو الكمبيوتر المفهوم المعروف باسم البرمجة المتوازية. في البرمجة المتوازية، يقوم المبرمجون بتطوير التعليمات البرمجية لتحقيق أفضل استخدام لوحدات المعالجة المركزية المتعددة.
مع وجود العديد من المجالات التي تستخدم كشط الويب لكشط البيانات من مواقع الويب، فإن العيب الكبير هو الوقت الذي يستغرقه كشط كميات هائلة من البيانات. إذا لم تكن مطورًا متمرسًا، فقد ينتهي بك الأمر إلى إضاعة الكثير من الوقت في تجربة تقنيات معينة قبل أن تقوم في النهاية بتشغيل الكود بشكل مثالي وخالٍ من الأخطاء.
يوضح القسم أدناه بعض الأسباب التي تجعل تجريف الويب بطيئًا.
أولاً، يجب على الكاشطة أن تنتقل إلى موقع الويب المستهدف في كشط الويب. ثم سيتعين عليه سحب واسترداد الكيانات من علامات HTML التي ترغب في كشطها. أخيرًا، في معظم الظروف، ستقوم بحفظ البيانات في ملف خارجي مثل تنسيق CSV.
لذا، كما ترى، فإن معظم المهام المذكورة أعلاه تتطلب عملية إدخال/إخراج مربوطة ثقيلة مثل سحب البيانات من مواقع الويب ثم حفظها في ملفات خارجية. غالبًا ما يعتمد التنقل إلى مواقع الويب المستهدفة على عوامل خارجية مثل سرعة الشبكة أو الانتظار لحين توفر الشبكة.
كما ترى في الشكل أدناه، قد يؤدي هذا الاستهلاك البطيء للغاية للوقت إلى إعاقة عملية الكشط عندما يتعين عليك كشط ثلاثة مواقع ويب أو أكثر. هذا على افتراض أنك تقوم بعملية الكشط بالتتابع.
لذلك بطريقة أو بأخرى، سيتعين عليك تطبيق التزامن أو التوازي على عمليات الكشط. سننظر في التوازي أولاً في القسم التالي.
أنا متأكد من أن لديك نظرة عامة على التزامن والتوازي الآن. سيركز هذا القسم على التزامن في كشط الويب مع مثال ترميز بسيط في Python.
في هذا المثال، سنقوم في هذا المثال بكشط عناوين URL للبلدان حسب قائمة العواصم بناءً على عدد السكان من ويكيبيديا. سيحفظ البرنامج الروابط ثم ينتقل إلى كل صفحة من الصفحات الـ 240 ويحفظ HTML لتلك الصفحات محلياً.
لتوضيح تأثيرات التزامن، سنعرض برنامجين - أحدهما ذو تنفيذ متسلسل والآخر متزامن مع خيوط متعددة.
إليك الرمز:
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import time
def get_countries():
countries = 'https://en.wikipedia.org/wiki/List_of_national_capitals_by_population'
all_countries = []
response = requests.get(countries)
soup = BeautifulSoup(response.text, "html.parser")
countries_pl = soup.select('th .flagicon+ a')
for link_pl in countries_pl:
link = link_pl.get("href")
link = urljoin(countries, link)
all_countries.append(link)
return all_countries
def fetch(link):
res = requests.get(link)
with open(link.split("/")[-1]+".html", "wb") as f:
f.write(res.content)
def main():
clinks = get_countries()
print(f"Total pages: {len(clinks)}")
start_time = time.time()
for link in clinks:
fetch(link)
duration = time.time() - start_time
print(f"Downloaded {len(links)} links in {duration} seconds")
main()
شرح الرمز
أولاً، نقوم باستيراد المكتبات، بما في ذلك BeautifulSoap، لاستخراج بيانات HTML. أما المكتبات الأخرى فتشمل مكتبة الطلب للوصول إلى الموقع الإلكتروني، ومكتبة urllib لضم عناوين URL كما ستكتشف، ومكتبة الوقت لمعرفة إجمالي وقت تنفيذ البرنامج.
استيراد الطلبات
من bs4 استيراد حساء جميل
من urllib.parse استيراد urljoin من URLjoin
استيراد الوقت
يبدأ البرنامج أولاً بالوحدة الرئيسية التي تستدعي دالة get_countries(). ثم تصل الدالة بعد ذلك إلى عنوان URL الخاص بويكيبيديا المحدد في متغير البلدان عبر مثيل BeautifulSoup من خلال محلل HTML.
ثم يبحث بعد ذلك عن عنوان URL لقائمة البلدان في الجدول عن طريق استخراج القيمة الموجودة في سمة href لعلامة الارتساء.
الروابط التي تسترجعها هي روابط نسبية. ستقوم دالة urljoin بتحويلها إلى روابط مطلقة. ثم يتم إلحاق هذه الروابط في مصفوفة all_countries، والتي تعيدها إلى الدالة الرئيسية
ثم تقوم دالة الجلب بحفظ محتوى HTML في كل رابط كملف HTML. هذا ما تفعله هذه الأجزاء من الشيفرة
تعريف إحضار (رابط):
res = الطلبات.get(link)
باستخدام open(link.split("/")[-1]+".html", "wb") كـ f:
f.write(res.content)
وأخيراً، تطبع الدالة الرئيسية الوقت الذي استغرقه حفظ الملفات بتنسيق HTML. في جهاز الكمبيوتر الخاص بنا، استغرق الأمر 131.22 ثانية.
حسنًا، يمكن بالتأكيد جعل هذا الوقت أسرع. سنكتشف ذلك في القسم التالي، حيث يتم تنفيذ البرنامج نفسه بخيوط متعددة.
في الإصدار متعدد الخيوط، سيتعين علينا إجراء تغييرات طفيفة حتى ينفذ البرنامج بشكل أسرع.
تذكّر أن التزامن يتعلق بإنشاء سلاسل رسائل متعددة وتنفيذ البرنامج. هناك طريقتان لإنشاء سلاسل الرسائل - يدويًا وباستخدام فئة ThreadPoolExecutor.
بعد إنشاء الخيوط يدويًا، يمكنك استخدام دالة الانضمام على جميع الخيوط للطريقة اليدوية. من خلال القيام بذلك، ستنتظر الطريقة الرئيسية حتى تكمل جميع الخيوط تنفيذها.
في هذا البرنامج، سنقوم بتنفيذ التعليمات البرمجية باستخدام فئة ThreadPoolExecutor التي تعد جزءًا من الوحدة النمطية للعقود الآجلة المتزامنة. لذا عليك أولاً وقبل كل شيء، عليك وضع السطر أدناه في البرنامج أعلاه.
من concurrent.futures.futures استيراد ThreadPoolExecutor
بعد ذلك، يمكنك تغيير حلقة التكرار التي تحفظ محتوى HTML بتنسيق HTML على النحو التالي:
مع ThreadPoolExecutor(max_workers=32) كمنفذ:
المنفِّذ.خريطة(جلب، كلنك)
تقوم الشيفرة أعلاه بإنشاء تجمع مؤشرات ترابط بحد أقصى 32 مؤشر ترابط. لكل وحدة معالجة مركزية، تختلف معلمة max_workers، وتحتاج إلى تجربة قيم مختلفة. لا يعني بالضرورة أنه كلما زاد عدد الخيوط كلما كان وقت التنفيذ أسرع.
لذا في جهاز الكمبيوتر الخاص بنا أنتج الناتج 15.14 ثانية، وهو أفضل بكثير مما كان عليه عند تنفيذه بالتتابع.
لذا قبل أن ننتقل إلى القسم التالي، إليك الشيفرة النهائية للبرنامج مع التنفيذ المتزامن:
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from concurrent.futures import ThreadPoolExecutor
import time
def get_countries():
countries = 'https://en.wikipedia.org/wiki/List_of_national_capitals_by_population'
all_countries = []
response = requests.get(countries)
soup = BeautifulSoup(response.text, "html.parser")
countries_pl = soup.select('th .flagicon+ a')
for link_pl in countries_pl:
link = link_pl.get("href")
link = urljoin(countries, link)
all_countries.append(link)
return all_countries
def fetch(link):
res = requests.get(link)
with open(link.split("/")[-1]+".html", "wb") as f:
f.write(res.content)
def main():
clinks = get_countries()
print(f"Total pages: {len(clinks)}")
start_time = time.time()
with ThreadPoolExecutor(max_workers=32) as executor:
executor.map(fetch, clinks)
duration = time.time()-start_time
print(f"Downloaded {len(clinks)} links in {duration} seconds")
main()
الآن نأمل أن تكون قد اكتسبت فهمًا للتنفيذ المتزامن. لمساعدتك على التحليل بشكل أفضل، دعنا نلقي نظرة على كيفية أداء نفس البرنامج في بيئة متعددة المعالجات مع عمليات تنفذ بشكل متوازٍ في وحدات معالجة مركزية متعددة.
عليك أولاً استيراد الوحدة المطلوبة :
من المعالجة المتعددة الاستيراد من Pool,cpu_count،cpu_count
توفر Python طريقة cpu_count()، والتي تحسب عدد وحدات المعالجة المركزية في جهازك. وهي بلا شك مفيدة في تحديد العدد الدقيق للمهام التي يمكن أن تؤديها بالتوازي.
الآن عليك استبدال الشيفرة البرمجية مع حلقة التكرار في التنفيذ المتسلسل بهذه الشيفرة البرمجية:
مع Pool (cpu_count()) كـ p:
p.map(fetch,clinks)
بعد تشغيل هذا الرمز، أنتج زمن تنفيذ إجمالي قدره 20.10 ثانية وهو أسرع نسبيًا من التنفيذ المتسلسل في البرنامج الأول.
في هذه المرحلة، نأمل أن يكون لديك نظرة عامة شاملة عن البرمجة المتوازية والمتسلسلة - يعتمد اختيار استخدام أحدهما على الآخر بشكل أساسي على السيناريو المحدد الذي واجهته.
بالنسبة لسيناريو كشط الويب، نوصي بالبدء بالتنفيذ المتزامن ثم الانتقال إلى حل موازٍ سيكون رائعًا. نأمل أن تكونوا قد استمتعتم بقراءة هذا المقال، ولا تنسوا أيضًا قراءة مقالات أخرى ذات صلة بكشط الويب مثل هذه في مدونتنا.