كيف تبني بوتًا وتؤتمت مهامك اليومية باستخدام بايثون
تتضمن معظم الوظائف مهامًا متكررة يمكن أتمتتها، مما يحرر جزءًا من وقتك الثمين ويسمح لك بالتركيز على أعمال أكثر أهمية وإبداعًا. هذا يجعل الأتمتة مهارة أساسية لا غنى عنها في عالم اليوم المتسارع. قد تتمكن مجموعة صغيرة من مهندسي الأتمتة المهرة وخبراء المجال من أتمتة العديد من المهام الأكثر مللاً في فرق عمل بأكملها، مما يعزز الإنتاجية ويقلل الأخطاء البشرية.
في هذا المقال، سنستكشف أساسيات أتمتة سير العمل باستخدام Python – لغة برمجة قوية وسهلة التعلم ومثالية للمبتدئين والمحترفين على حد سواء. سنستخدم Python لكتابة سكريبت أتمتة بسيط ومفيد يعمل على تنظيف مجلد معين ووضع كل ملف في مجلده المناسب بناءً على نوعه. هدفنا في البداية لن يكون كتابة كود مثالي أو إنشاء معماريات برمجية معقدة، ولن نبني أي شيء “غير قانوني”. بدلاً من ذلك، سنركز على كيفية إنشاء سكريبت ينظم مجلدًا معينًا وجميع ملفاته تلقائيًا، مما يوفر لك الوقت والجهد.
مجالات الأتمتة ونقطة البداية
لنبدأ بتحديد أنواع الأتمتة المختلفة المتاحة. فن الأتمتة ينطبق على معظم القطاعات والصناعات. على سبيل المثال، يمكن أن يساعد في مهام بسيطة مثل استخراج عناوين البريد الإلكتروني من مجموعة من المستندات لإرسال حملات بريدية، أو في مقاربات أكثر تعقيدًا مثل تحسين سير العمل والعمليات داخل الشركات الكبرى. بالطبع، الانتقال من سكريبتات شخصية صغيرة إلى بنية تحتية ضخمة للأتمتة تحل محل الأشخاص يتطلب عملية تعلم وتطوير مستمرة. لذا، دعنا نرى من أين يمكنك بدء رحلتك في عالم الأتمتة.
الأتمتة البسيطة
تتيح الأتمتة البسيطة نقطة دخول سريعة ومباشرة إلى هذا المجال. يمكن أن تغطي هذه الأتمتة عمليات مستقلة صغيرة مثل تنظيف المشاريع وإعادة هيكلة الملفات داخل الدلائل، أو أجزاء من سير العمل مثل تغيير حجم الملفات المحفوظة تلقائيًا. هذه المهام غالبًا ما تكون متكررة وتستهلك وقتًا، والأتمتة هنا توفر حلولًا فورية وفعالة.
أتمتة واجهات برمجة التطبيقات العامة (Public API)
تُعد أتمتة واجهات برمجة التطبيقات العامة (Public API) الشكل الأكثر شيوعًا للأتمتة نظرًا لإمكانية الوصول إلى معظم الوظائف باستخدام طلبات HTTP إلى واجهات API في الوقت الحاضر. على سبيل المثال، إذا كنت ترغب في أتمتة ري حديقتك الذكية المصممة منزليًا، يمكنك التحقق من طقس اليوم الحالي لمعرفة ما إذا كنت بحاجة إلى الري أو إذا كان هناك مطر قادم، وذلك عن طريق استدعاء API لخدمة الطقس.
هندسة واجهات برمجة التطبيقات العكسية (API Reverse Engineering)
تُعد الأتمتة القائمة على هندسة واجهات برمجة التطبيقات العكسية (API Reverse Engineering) أكثر شيوعًا في البوتات الفعلية وفي قسم “المحتالون من البوتات” (Bot Imposter) ضمن الرسم البياني في قسم “الاعتبارات الأخلاقية” أدناه. من خلال الهندسة العكسية لواجهة API، نفهم تدفق المستخدم للتطبيقات. مثال على ذلك يمكن أن يكون تسجيل الدخول إلى لعبة متصفح عبر الإنترنت. بفهم عملية تسجيل الدخول والمصادقة، يمكننا تكرار هذا السلوك باستخدام سكريبت خاص بنا. بعد ذلك، يمكننا إنشاء واجهة خاصة بنا للعمل مع التطبيق حتى لو لم يوفروا ذلك بأنفسهم. مهما كان النهج الذي تستهدفه، ضع في اعتبارك دائمًا ما إذا كان قانونيًا أم لا. لا تريد أن تقع في المشاكل، أليس كذلك؟
اعتبارات أخلاقية في الأتمتة
تواصل معي ذات مرة أحدهم على منصة GitHub وقال لي: “الإعجابات والتفاعل هما عملة رقمية، وأنت تقلل من قيمتهما.” هذه العبارة بقيت في ذهني وجعلتني أتساءل عن الأداة التي بنيتها لهذا الغرض تحديدًا. حقيقة أن هذه التفاعلات والمشاركات يمكن أتمتتها و”تزييفها” بشكل متزايد تؤدي إلى نظام وسائل تواصل اجتماعي مشوه ومعطل. الأشخاص الذين ينتجون محتوى قيّمًا وجيدًا يصبحون غير مرئيين للمستخدمين الآخرين وشركات الإعلان إذا لم يستخدموا البوتات وأنظمة التفاعل الأخرى.
ابتكر صديق لي الربط التالي مع “الدوائر التسع للجحيم” لدانتي، حيث مع كل خطوة تقترب فيها من أن تصبح مؤثرًا اجتماعيًا، تصبح أقل وعيًا بمدى تعطل هذا النظام بأكمله. أرغب في مشاركة هذا معكم هنا لأنني أعتقد أنه تمثيل دقيق للغاية لما شهدته أثناء عملي بنشاط مع المؤثرين باستخدام أداة InstaPy.
- المستوى 1: المطهر (Limbo) – إذا لم تستخدم البوتات على الإطلاق.
- المستوى 2: المغازلة (Flirtation) – عندما تقوم يدويًا بالإعجاب والمتابعة لأكبر عدد ممكن من الأشخاص لجعلهم يتابعونك أو يعجبون بمنشوراتك.
- المستوى 3: التآمر (Conspiracy) – عندما تنضم إلى مجموعة على
Telegramللإعجاب والتعليق على 10 صور لكي يقوم العشرة أشخاص التاليين بالإعجاب والتعليق على صورتك. - المستوى 4: الخيانة (Infidelity) – عندما تستخدم مساعدًا افتراضيًا منخفض التكلفة (
Virtual Assistant) للإعجاب والمتابعة نيابة عنك. - المستوى 5: الشهوة (Lust) – عندما تستخدم بوتًا لإعطاء الإعجابات، ولا تتلقى أي إعجابات في المقابل (لكن لا تدفع ثمنه – على سبيل المثال، إضافة متصفح
Chrome). - المستوى 6: الفجور (Promiscuity) – عندما تستخدم بوتًا لإعطاء أكثر من 50 إعجابًا للحصول على أكثر من 50 إعجابًا، لكن لا تدفع ثمنه – على سبيل المثال، إضافة متصفح
Chrome. - المستوى 7: الطمع أو الجشع الشديد (Avarice or Extreme Greed) – عندما تستخدم بوتًا للإعجاب/المتابعة/التعليق على ما بين 200 إلى 700 صورة، متجاهلاً فرصة الحظر.
- المستوى 8: الدعارة (Prostitution) – عندما تدفع لخدمة طرف ثالث غير معروف للمشاركة في إعجابات/متابعات متبادلة مؤتمتة لك، لكنهم يستخدمون حسابك للإعجاب/المتابعة بالمقابل.
- المستوى 9: الاحتيال/الهرطقة (Fraud / Heresy) – عندما تشتري متابعين وإعجابات وتحاول بيع نفسك للعلامات التجارية كمؤثر.
إن مستوى استخدام البوتات على وسائل التواصل الاجتماعي منتشر لدرجة أنه إذا لم تستخدم البوتات، فستظل عالقًا في المستوى 1: المطهر (Limbo)، بدون نمو في المتابعين وتفاعل منخفض نسبيًا مقارنة بأقرانك. في النظرية الاقتصادية، يُعرف هذا بمعضلة السجين (prisoner's dilemma) ولعبة المحصلة الصفرية (zero-sum game). إذا لم أستخدم البوتات وأنت استخدمتها، فأنت تفوز. إذا لم تستخدم البوتات وأنا استخدمتها، فأنا أفوز. إذا لم يستخدم أحد البوتات، فالجميع يفوز. ولكن بما أنه لا يوجد حافز للجميع لعدم استخدام البوتات، فالجميع يستخدمها، وبالتالي لا أحد يفوز. كن على دراية بذلك ولا تنس أبدًا الآثار المترتبة على هذه الأدوات بأكملها على وسائل التواصل الاجتماعي.

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

إعداد محلل الوسائط (Argument Parser)
نظرًا لأننا نعمل مع وظائف نظام التشغيل مثل نقل الملفات، نحتاج إلى استيراد مكتبة os. بالإضافة إلى ذلك، نريد منح المستخدم بعض التحكم في المجلد الذي سيتم تنظيفه. سنستخدم مكتبة argparse لهذا الغرض.
import os
import argparse
بعد استيراد المكتبتين، دعنا أولاً نعد محلل الوسائط (argument parser). تأكد من توفير وصف ونص مساعدة لكل وسيطة مضافة لتقديم مساعدة قيّمة للمستخدم عندما يكتب --help. ستكون وسيطتنا باسم --path. الشرطتان المزدوجتان أمام الاسم تخبران المكتبة أن هذه وسيطة اختيارية. افتراضيًا، نريد استخدام الدليل الحالي، لذا اضبط القيمة الافتراضية لتكون ".".
parser = argparse.ArgumentParser(
description="Clean up directory and put files into according folders."
)
parser.add_argument(
"--path",
type=str,
default=".",
help="Directory path of the to be cleaned directory",
)
# parse the arguments given by the user and extract the path
args = parser.parse_args()
path = args.path
print(f"Cleaning up directory {path}")
هذا ينهي بالفعل قسم تحليل الوسائط – إنه بسيط وواضح تمامًا، أليس كذلك؟ دعنا ننفذ سكريبتنا ونتحقق من الأخطاء.
python directory_clean.py --path ./test
=> Cleaning up directory ./test
بمجرد التنفيذ، يمكننا رؤية اسم الدليل مطبوعًا على وحدة التحكم، ممتاز. دعنا الآن نستخدم مكتبة os للحصول على ملفات المسار المحدد.
الحصول على قائمة الملفات من المجلد
باستخدام الدالة os.listdir(path) وتزويدها بمسار صالح، نحصل على قائمة بجميع الملفات والمجلدات داخل هذا الدليل. بعد سرد جميع العناصر في المجلد، نريد التمييز بين الملفات والمجلدات لأننا لا نرغب في تنظيف المجلدات، بل الملفات فقط. في هذه الحالة، نستخدم قائمة فهم في Python (Python list comprehension) للتكرار عبر جميع العناصر ووضعها في قوائم جديدة إذا استوفت الشرط المحدد بأن تكون ملفًا أو مجلدًا.
# get all files from given directory
dir_content = os.listdir(path)
# create a relative path from the path to the file and the document name
path_dir_content = [os.path.join(path, doc) for doc in dir_content]
# filter our directory content into a documents and folders list
docs = [doc for doc in path_dir_content if os.path.isfile(doc)]
folders = [folder for folder in path_dir_content if os.path.isdir(folder)]
# counter to keep track of amount of moved files
# and list of already created folders to avoid multiple creations
moved = 0
created_folders = []
print(f"Cleaning up {len(docs)} of {len(dir_content)} elements.")
كما هو الحال دائمًا، دعنا نتأكد من حصول مستخدمينا على ملاحظات. لذا أضف عبارة طباعة (print statement) تعطي المستخدم إشارة حول عدد الملفات التي سيتم نقلها.
python directory_clean.py --path ./test
=> Cleaning up directory ./test
=> Cleaning up 60 of 60 elements.
بعد إعادة تنفيذ سكريبت Python، يمكننا الآن رؤية أن مجلد /test الذي أنشأته يحتوي على 60 ملفًا سيتم نقلها.
إنشاء مجلد لكل امتداد ملف
الخطوة التالية والأكثر أهمية الآن هي إنشاء مجلد لكل امتداد ملف. نريد القيام بذلك عن طريق المرور عبر جميع ملفاتنا المفلترة، وإذا كان لديها امتداد لا يوجد له مجلد بالفعل، نقوم بإنشاء واحد. تساعدنا مكتبة os بوظائف لطيفة أخرى مثل تقسيم نوع الملف ومساره من مستند معين، واستخراج المسار نفسه واسم المستند.
# go through all files and move them into according folders
for doc in docs:
# separte name from file extension
full_doc_path, filetype = os.path.splitext(doc)
doc_path = os.path.dirname(full_doc_path)
doc_name = os.path.basename(full_doc_path)
print(filetype)
print(full_doc_path)
print(doc_path)
print(doc_name)
break
تضمن عبارة break في نهاية الكود أعلاه عدم إغراق طرفيتنا بالرسائل إذا كان دليلنا يحتوي على عشرات الملفات. بمجرد إعداد هذا، دعنا ننفذ سكريبتنا لرؤية مخرجات مشابهة لهذا:
python directory_clean.py --path ./test
=> ...
=> .pdf
=> ./test/test17
=> ./test
=> test17
يمكننا الآن رؤية أن التنفيذ أعلاه يفصل نوع الملف ثم يستخرج الأجزاء من المسار الكامل. بما أن لدينا نوع الملف الآن، يمكننا التحقق مما إذا كان مجلد يحمل اسم هذا النوع موجودًا بالفعل. قبل القيام بذلك، نريد التأكد من تخطي بعض الملفات. إذا استخدمنا الدليل الحالي "." كمسار، فنحن بحاجة إلى تجنب نقل سكريبت Python نفسه. شرط if بسيط يعالج ذلك. بالإضافة إلى ذلك، لا نريد نقل الملفات المخفية (Hidden Files)، لذا دعنا نضمن أيضًا جميع الملفات التي تبدأ بنقطة. ملف .DS_Store على نظام macOS هو مثال على ملف مخفي.
# skip this file when it is in the directory
if doc_name == "directory_clean" or doc_name.startswith('.'):
continue
# get the subfolder name and create folder if not exist
subfolder_path = os.path.join(path, filetype[1:].lower())
if subfolder_path not in folders:
# create the folder
بمجرد أن نكون قد عالجنا سكريبت Python والملفات المخفية، يمكننا الآن الانتقال إلى إنشاء المجلدات على النظام. بالإضافة إلى فحصنا، إذا كان المجلد موجودًا بالفعل عندما قرأنا محتوى الدليل في البداية، فنحن بحاجة إلى طريقة لتتبع المجلدات التي أنشأناها بالفعل. لهذا السبب أعلنا عن قائمة created_folders = []. ستعمل كذاكرة لتتبع أسماء المجلدات. لإنشاء مجلد جديد، توفر مكتبة os دالة تسمى os.mkdir(folder_path) تأخذ مسارًا وتنشئ مجلدًا بالاسم المحدد هناك. قد تطلق هذه الدالة استثناءً، تخبرنا أن المجلد موجود بالفعل. لذا دعنا نتأكد أيضًا من التقاط هذا الخطأ.
if subfolder_path not in folders and subfolder_path not in created_folders:
try:
os.mkdir(subfolder_path)
created_folders.append(subfolder_path)
print(f"Folder {subfolder_path} created.")
except FileExistsError as err:
print(f"Folder already exists at {subfolder_path} ... {err}")
بعد إعداد إنشاء المجلدات، دعنا نعيد تنفيذ سكريبتنا.
python directory_clean.py --path ./test
=> ...
=> Folder ./test/pdf created.
في أول تشغيل للتنفيذ، يمكننا رؤية قائمة من السجلات تخبرنا أن المجلدات بأنواع امتدادات الملفات المحددة قد تم إنشاؤها.
نقل كل ملف إلى المجلد الفرعي الصحيح
الخطوة الأخيرة الآن هي نقل الملفات فعليًا إلى مجلداتها الأصلية الجديدة. من المهم فهم أنه عند العمل مع عمليات os، قد لا يمكن التراجع عن بعض العمليات. هذا هو الحال، على سبيل المثال، مع الحذف. لذا من المنطقي أولاً تسجيل السلوك الذي سيحققه سكريبتنا إذا قمنا بتنفيذه. لهذا السبب تم التعليق على دالة os.rename(...) هنا.
# get the new folder path and move the file
new_doc_path = os.path.join(subfolder_path, doc_name) + filetype
# os.rename(doc, new_doc_path)
moved += 1
print(f"Moved file {doc} to {new_doc_path}")
بعد تنفيذ سكريبتنا ورؤية التسجيل الصحيح، يمكننا الآن إزالة علامة التعليق (#) قبل دالة os.rename() الخاصة بنا وإعطائها محاولة أخيرة.
# get the new folder path and move the file
new_doc_path = os.path.join(subfolder_path, doc_name) + filetype
os.rename(doc, new_doc_path)
moved += 1
print(f"Moved file {doc} to {new_doc_path}")
print(f"Renamed {moved} of {len(docs)} files.")
python directory_clean.py --path ./test
=> ...
=> Moved file ./test/test17.pdf to ./test/pdf/test17.pdf
=> ...
=> Renamed 60 of 60 files.
سيقوم هذا التنفيذ النهائي الآن بنقل جميع الملفات إلى مجلداتها المناسبة وسيتم تنظيف دليلنا بشكل جيد دون الحاجة إلى إجراءات يدوية. في الخطوة التالية، يمكننا الآن استخدام السكريبت الذي أنشأناه أعلاه، وعلى سبيل المثال، جدولته للتنفيذ كل يوم اثنين لتنظيف مجلد التنزيلات (Downloads) الخاص بنا لمزيد من التنظيم. هذا بالضبط ما نقوم بإنشائه كمتابعة داخل دورتنا التدريبية على Udemy بعنوان “إنشاء البوتات وأتمتة سير العمل” (Bot Creation and Workflow Automation).
لقد قمت أنا وزميلي فيليكس ببناء دورة فيديو عبر الإنترنت لتعليمك كيفية إنشاء البوتات الخاصة بك بناءً على ما تعلمناه من بناء InstaPy وبوت Travian الخاص به. في الواقع، لقد اضطر حتى إلى إزالته لأنه كان فعالًا للغاية. انضم الآن وابدأ التعلم. إذا كان لديك أي أسئلة أو ملاحظات، فلا تتردد في التواصل معنا على Twitter أو مباشرة في قسم المناقشة في الدورة.
الخلاصة التقنية
يُظهر هذا المقال بوضوح كيف يمكن لأدوات الأتمتة، وخاصة تلك المبنية بلغة Python، أن تُحدث ثورة في إدارة المهام اليومية. من خلال سكريبت بسيط لتنظيف المجلدات، استعرضنا قوة الأتمتة في تبسيط العمليات المتكررة، مما يوفر وقتًا ثمينًا ويزيد من الكفاءة. الأهم من ذلك، أن المقال لم يغفل الجانب الأخلاقي الحيوي لاستخدام البوتات، مقدمًا منظورًا نقديًا حول تأثيرها على التفاعلات الرقمية. هذا التوازن بين التطبيق العملي والوعي الأخلاقي يجعل من هذا الدليل مرجعًا قيمًا لأي شخص يسعى لاستغلال إمكانات الأتمتة بمسؤولية وفعالية.