سكربت بايثون لكتابة مقالات متوافقة مع السيو هو أداة برمجية تربط نموذج ذكاء اصطناعي (مثل Claude أو GPT) بمحرك قواعد SEO ثابتة، ثم تُخرج مقالاً جاهزاً بصيغة HTML يحترم بنية BLUF، وSchema Markup، والربط الداخلي، وقيود Rate Limits، قبل نشره تلقائياً عبر WordPress REST API. الفكرة الجوهرية أن النموذج وحده لا يضمن الالتزام بمعايير السيو؛ الضبط الصارم يأتي من الكود الذي يحيط استدعاء الذكاء الاصطناعي بقواعد تحقق (validation) قبل وبعد التوليد. هل تريد أنشاء سكربت لتوليد وكتابة مقالات تتصدر بها محركات البحث أقرأ الاسطر القليلة القادمة باختصار وأنت تعرف وتفهم كل شئ.
باختصار، السكربت الجيد يقوم بأربع مهام متسلسلة:
- يبني Prompt هيكلي يحتوي على الكلمة المفتاحية، الجمهور، ونية البحث.
- يستدعي واجهة برمجية للذكاء الاصطناعي مع ضبط drift عبر system prompt صارم.
- يفحص الناتج آليًا من حيث طول النص، وبنيته الأساسية، ووجود عناصر تحتاج إلى مراجعة قبل النشر، ثم يضيف طبقة Schema وروابط داخلية قبل إرساله إلى WordPress كمسودة.
- ينشر المقال عبر WordPress REST API مع ضبط الحالة (مسودة أو منشور) والصورة البارزة.
هذا الدليل يشرح كل مرحلة من هذه المراحل بكود عملي قابل للتطبيق مباشرة، ويعالج نقاطاً كثيراً ما تُهمَل في الأدلة المشابهة: التعامل مع الهلوسة (Hallucinations)، وحدود معدل الطلبات (Rate Limits)، والربط الداخلي الذكي بدل العشوائي.
أن كنت تريد إنشاء سكربت Python ينشر مقالات SEO تلقائياً على WordPress في 2026 هذا شرح كامل ويعتبر أفضل دليل لك فهو دليل عملى بالاضافة وجود اكواد جاهزة سوف تستخدمها بكب سهولة ويسر فتابع الشرح بالتفصيل.
راجع مقالنا عن ما هو Claude AI؟ شرح شامل للمبتدئين + الاستخدامات والمقارنة مع ChatGPT و Gemini فى 2026.
وراجع مقالنا عن شرح ChatGPT خطوة بخطوة للمبتدئين 2026 | دليل استخدام شات جي بي تي.
المتطلبات الأساسية لبناء سكربت كتابة مقالات SEO ببايثون
قبل كتابة أي سطر كود، تحتاج ثلاثة عناصر جاهزة: مفتاح API لنموذج ذكاء اصطناعي، بيئة بايثون بها مكتبات محددة، وموقع WordPress مفعّل عليه REST API مع مستخدم Application Password. تجهيز هذه العناصر مسبقاً يوفر عليك أخطاء التنفيذ لاحقاً.
Best Practice: لا تبدأ بربط السكربت مباشرة بحساب WordPress الإنتاجي (Production). أنشئ بيئة اختبار (Staging) أو موقعاً تجريبياً محلياً أولاً، لأن أي خطأ في منطق النشر التلقائي قد يؤدي إلى نشر عشرات المقالات الناقصة دفعة واحدة.
| المتطلب | الغرض | ملاحظة عملية |
|---|---|---|
مكتبة anthropic | الاتصال بنموذج Claude لتوليد النص | استخدم أحدث إصدار مستقر متوافق مع streaming |
مكتبة requests | التواصل مع WordPress REST API | تُستخدم أيضاً لرفع الصور كوسائط |
مكتبة python-dotenv | حماية مفاتيح API | لا تكتب المفاتيح مباشرة داخل الكود أبداً |
| Application Password في WordPress | مصادقة النشر عبر REST API | يُنشأ من صفحة “المستخدمون” وليس كلمة المرور الرئيسية |
| Beautiful Soup أو lxml | فحص صحة وسوم HTML قبل النشر | يساعد على تحليل HTML والتحقق من بنيته قبل النشر. |
تحذير: استخدام كلمة مرور حساب المدير الرئيسي مباشرة في السكربت خطأ أمني شائع. Application Password في WordPress مخصصة لهذا الغرض تحديداً لأنها قابلة للإلغاء دون التأثير على الحساب الأساسي، وهذا فرق جوهري يغفل عنه كثير من الدروس المشابهة.
كيف تبني سكربت Python يولّد المقال وفق قواعد السيو؟
جوهر السكربت هو دالة تبني System Prompt صارماً يفرض بنية BLUF وحدود الطول، ثم تمرره لنموذج الذكاء الاصطناعي وتستقبل الناتج كنص HTML خام. الفرق بين سكربت هاوٍ وسكربت احترافي هو مدى تفصيل هذا الـ Prompt ومدى إحكام معالجة الاستجابة بعده.
import os
import time
import anthropic
from dotenv import load_dotenv
load_dotenv()
client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
def build_seo_prompt(keyword, audience, intent, min_words=2500, max_words=3500):
return f"""
الكلمة المفتاحية: {keyword}
الجمهور المستهدف: {audience}
نية البحث: {intent}
أنشئ مقالاً أصلياً ومفيداً باللغة العربية.
استخدم البنية التالية:
{{
"title": "عنوان المقال",
"content": "<p>...</p><h2>...</h2>...",
"faq": [
{{
"question": "السؤال الأول",
"answer": "الإجابة..."
}}
],
"meta_description": "وصف مختصر للمقال"
}}
قواعد المحتوى:
- يبدأ content بفقرة تجيب عن نية البحث مباشرة (BLUF)، لا تقل عن 50 كلمة.
- طول المحتوى بين {min_words} و{max_words} كلمة تقريباً.
- استخدم HTML فقط داخل content: h2, h3, p, ul, ol, table, pre, code.
- لا تضف Schema داخل content؛ سيقوم Python ببنائه لاحقاً.
- لا تخترع إحصاءات أو أرقاماً غير موثقة.
- اجعل الأسئلة الشائعة مرتبطة مباشرة بموضوع المقال.
"""
def generate_article(keyword, audience, intent, retries=3):
system_prompt = """أنت محرر تقني متخصص في مقالات SEO باللغة العربية.
أرجع الناتج بصيغة JSON صالح فقط دائماً، بدون Markdown أو ``` أو أي نص خارج JSON."""
user_prompt = build_seo_prompt(keyword, audience, intent)
for attempt in range(retries):
try:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=8000,
system=system_prompt,
messages=[
{"role": "user", "content": user_prompt},
{"role": "assistant", "content": "{"}
]
)
return "{" + response.content[0].text
except anthropic.RateLimitError:
wait = (2 ** attempt) * 5
time.sleep(wait)
raise RuntimeError("فشل التوليد بعد عدة محاولات بسبب Rate Limits")
الأسطر الحرجة هنا هي منطق retries مع Exponential Backoff داخل generate_article. دون هذه الآلية، أي سكربت يشغّل عشرات المقالات دفعة واحدة سيتوقف عند أول خطأ Rate Limit بدل أن يعيد المحاولة تلقائياً بفارق زمني متصاعد.
استخدام Structured Output لتنظيم مخرجات النموذج
بدلاً من مطالبة نموذج الذكاء الاصطناعي بإرجاع HTML فقط، من الأفضل أن يعيد النتيجة في بنية منظمة تحتوي على عناصر المقال الرئيسية. بهذه الطريقة يستطيع Python التعامل مع العنوان والمحتوى والأسئلة الشائعة والوصف التعريفي كل عنصر على حدة، بدلاً من محاولة استخراجها لاحقاً من نص HTML غير منظم.
يمكن أن تكون البنية الأساسية للمخرجات بهذا الشكل:
{
"title": "عنوان المقال",
"content": "<h2>...</h2><p>...</p>",
"faq": [
{
"question": "السؤال الأول",
"answer": "الإجابة..."
},
{
"question": "السؤال الثاني",
"answer": "الإجابة..."
}
],
"meta_description": "وصف مختصر للمقال"
}
بعد ذلك يستطيع السكربت التعامل مع كل عنصر بشكل مستقل: فحص العنوان، والتحقق من المحتوى، وبناء البيانات المنظمة من أسئلة FAQ، ومراجعة الوصف التعريفي، وإضافة الروابط الداخلية، ثم إرسال المحتوى النهائي إلى WordPress.
هذه الطريقة أفضل من الاعتماد على HTML خام فقط، لأنها تفصل المحتوى عن البيانات الوصفية وتقلل الحاجة إلى تحليل النص لاحقاً باستخدام تعبيرات منتظمة أو عمليات استخراج هشة.
import json
def parse_article_response(response_text):
"""تحويل استجابة النموذج إلى بنية Python منظمة."""
try:
article = json.loads(response_text)
except json.JSONDecodeError as exc:
raise ValueError(
f"تعذر تحليل استجابة النموذج كـ JSON: {exc}"
)
required_fields = [
"title",
"content",
"faq",
"meta_description"
]
missing_fields = [
field for field in required_fields
if field not in article
]
if missing_fields:
raise ValueError(
f"الاستجابة تفتقد الحقول التالية: {missing_fields}"
)
return article
وظيفة parse_article_response() هي تحويل استجابة النموذج من JSON إلى كائن Python يمكن فحصه ومعالجته. وإذا كان أحد الحقول الأساسية مفقودًا، يتوقف السكربت بدل إرسال محتوى ناقص إلى مراحل النشر.
وهنا يصبح الـWorkflow أقوى بكثير
بدل أن يكون:
الكلمة المفتاحية
↓
Prompt
↓
Claude
↓
HTML
↓
WordPress
سيصبح:
الكلمة المفتاحية
↓
Search Intent
↓
Structured Prompt
↓
Claude / GPT
↓
JSON
↓
Python Validation
↓
فحص Title
↓
فحص Content
↓
فحص FAQ
↓
Meta Description
↓
Internal Links
↓
Schema
↓
WordPress Draft
وهذا هو السبب الذي يجعلني أعتبر Structured Output إضافة مهمة جدًا للمقال.
Structured Output لا يمنع الهلوسة المعرفية، لكنه يجعل مخرجات النموذج أكثر قابلية للتحقق والمعالجة آليًا، ويسمح للسكربت برفض الاستجابة إذا كانت البنية المطلوبة ناقصة أو غير صالحة.
Performance Note: تشغيل التوليد بشكل متزامن (Sequential) لعشرات المقالات بطيء وقد يستغرق ساعات. حل عملي هو معالجة المقالات على دفعات صغيرة (Batching) مع فاصل زمني ثابت بين كل طلب وآخر، بدل الاندفاع نحو التوازي الكامل الذي يصطدم بسرعة بحدود معدل الطلبات.
إضافة Schema Markup والربط الداخلي وفحص جودة المقال
توليد النص وحده لا يكفي؛ المقال يحتاج طبقة تحقق آلي بعد التوليد تتأكد من وجود البيانات المنظمة وصحة بنيتها، إلى جانب الروابط الداخلية وفحص بعض المؤشرات التي قد تحتاج إلى مراجعة بشرية.
import json
import re
from bs4 import BeautifulSoup
def build_faq_schema(faq_pairs):
return json.dumps({
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": question,
"acceptedAnswer": {
"@type": "Answer",
"text": answer
}
}
for question, answer in faq_pairs
]
}, ensure_ascii=False, indent=2)
def count_words(html_text):
"""حساب عدد كلمات النص الظاهرة للمستخدم بعد إزالة وسوم HTML."""
soup = BeautifulSoup(html_text, "html.parser")
text = soup.get_text(" ", strip=True)
return len(re.findall(r"\S+", text))
def get_first_paragraph(html_text):
"""استخراج أول فقرة نصية من المقال."""
soup = BeautifulSoup(html_text, "html.parser")
paragraph = soup.find("p")
if paragraph:
return paragraph.get_text(" ", strip=True)
return ""
def check_quality(html_text, min_words=2500):
"""فحص أولي لجودة المقال قبل إرساله إلى WordPress."""
word_count = count_words(html_text)
first_paragraph = get_first_paragraph(html_text)
issues = []
if word_count < min_words:
issues.append(
f"عدد الكلمات ({word_count}) أقل من الحد الأدنى المطلوب ({min_words})."
)
if not first_paragraph:
issues.append(
"لا توجد فقرة افتتاحية في المقال."
)
elif len(first_paragraph.split()) < 30:
issues.append(
"الفقرة الافتتاحية قصيرة وتحتاج إلى مراجعة تحريرية."
)
suspicious_numbers = re.findall(
r"\b\d{2,}%|\$\d+(?:\.\d+)?",
html_text
)
if suspicious_numbers:
issues.append(
"توجد أرقام أو نسب تحتاج إلى مراجعة مصدرية: "
+ ", ".join(suspicious_numbers)
)
return issues
الجزء الأهم في هذا الكود هو suspicious_numbers: أي نسبة مئوية أو رقم مالي يُولّده النموذج دون مصدر واضح يُعتبر مرشحاً قوياً للهلوسة، لذا يُفضَّل وسمه للمراجعة اليدوية بدل نشره تلقائياً كحقيقة مؤكدة.
Decision Tip: اربط الفقرة الداخلية بمقالات موجودة فعلياً على موقعك عبر قاعدة بيانات محلية (ملف JSON أو جدول SQLite) تحتوي على عناوين وروابط مقالاتك السابقة، بدل ترك النموذج يخترع Anchor Text لصفحات غير موجودة، وهو خطأ شائع يضر بتجربة المستخدم ومصداقية السيو معاً.
سيناريو تطبيقي: من الكلمة المفتاحية إلى مقال جاهز للنشر
لنفترض أن الكلمة المفتاحية هي “أفضل أدوات إدارة المهام للفرق الصغيرة”. تمر العملية بأربع خطوات فعلية: توليد المسودة، فحص الجودة، حقن Schema والروابط الداخلية، ثم التجهيز للنشر كمسودة (Draft) بانتظار المراجعة البشرية.
| الخطوة | الأداة/الدالة | الناتج المتوقع |
|---|---|---|
| 1. التوليد | generate_article() | نص HTML خام بصيغة BLUF |
| 2. الفحص | check_quality() | قائمة مشاكل أو تأكيد الصلاحية |
| 3. حقن Schema | build_faq_schema() | سكربت JSON-LD مضمّن في نهاية الصفحة |
| 4. التجهيز للنشر | publish_to_wordpress() | معرّف مقال (Post ID) بحالة “مسودة” |
مقارنة مدعومة بالتقرير: الفرق الجوهري بين توليد مقال واحد يدوياً وتشغيل السيناريو الكامل آلياً هو نقطة المراجعة البشرية؛ التوصية العملية هي إبقاء حالة النشر الافتراضية “مسودة” دائماً، وعدم تفعيل النشر المباشر (Publish) إلا بعد مراجعة السكربت لدفعات كافية من المقالات وثبات جودتها.
النشر في WordPress والقيود والأسئلة الشائعة
النشر يتم عبر نقطة النهاية /wp-json/wp/v2/posts باستخدام مصادقة Basic Auth عبر Application Password. الدالة التالية ترسل عنوان المقال والمحتوى وحالة النشر، وتُرجع رابط المقال أو رسالة الخطأ إن فشل الطلب.
def publish_to_wordpress(site_url, title, html_content, status="draft"):
endpoint = f"https://www.aicodesmart.com/wp-json/wp/v2/posts"
auth = HTTPBasicAuth(
os.getenv("WP_USERNAME"),
os.getenv("WP_APP_PASSWORD")
)
payload = {"title": title, "content": html_content, "status": status}
response = requests.post(endpoint, json=payload, auth=auth, timeout=30)
response.raise_for_status()
return response.json().get("link")
أهم سطر هنا هو response.raise_for_status()، لأن تجاهل رموز الخطأ (كرمز 401 عند فشل المصادقة أو 400 عند محتوى مرفوض) يجعل السكربت يبدو ناجحاً في اللوغ بينما لا شيء يُنشر فعلياً على الموقع.
على مستوى القيود، أهمها ثلاثة: حدود معدل طلبات نموذج الذكاء الاصطناعي (تختلف حسب الخطة المشترك بها)، وحدود حجم الطلب في REST API (بعض استضافات WordPress تحدّ حجم الـ payload)، واحتمال حجب الطلبات من بعض جدران الحماية (WAF) إذا جاءت من عنوان IP غير مألوف بمعدل مرتفع.
هل المقالات التي يكتبها سكربت Python متوافقة مع Google SEO؟
جوجل لا تعاقب على استخدام الذكاء الاصطناعى فى توليد المقالات اليا ولكن لابد من لمسة بشرية، لذلك:
- استخدام AI بحد ذاته ليس المشكلة.
- المشكلة هي إنتاج صفحات كثيرة دون قيمة للمستخدم.
- المحتوى يجب أن يكون مفيدًا وموثوقًا.
- المراجعة البشرية مهمة عندما تكون الدقة والخبرة مطلوبة.
- لا يوجد سكربت يضمن المركز الأول.
Google تقول صراحة إن استخدام الذكاء الاصطناعي يمكن أن يكون مفيدًا، لكن إنشاء صفحات كثيرة بالـAI دون إضافة قيمة للمستخدم قد يدخل ضمن سياسة scaled content abuse.
ما الذي لا يستطيع سكربت Python ضمانه؟
| ما يستطيع السكربت فعله | ما لا يستطيع ضمانه |
|---|---|
| إنشاء هيكل المقال | صحة كل معلومة |
| فحص عدد الكلمات | جودة الخبرة البشرية |
| إضافة روابط | أن الرابط هو الأفضل دائمًا |
| إنشاء Schema | ظهور Rich Result |
| النشر في WordPress | تصدر Google |
| كشف بعض الأنماط | اكتشاف كل هلوسة |
وهذه نقطة مهمة جدًا لأن Google لا تضمن ظهور Structured Data حتى عندما تكون صحيحة.
مقارنة بين Claude وGPT من ناحية بناء النظام
| الطريقة | التحكم | Validation | WordPress | مناسبة للأتمتة |
|---|---|---|---|---|
| AI Chat فقط | منخفض | منخفض | لا | منخفض |
| Python + AI | متوسط | متوسط | ممكن | جيد |
| Python + AI + Validation | مرتفع | مرتفع | ممكن | ممتاز |
| Full Workflow | مرتفع جدًا | مرتفع | نعم | ممتاز جدًا |
دليل عملي: بناء سكربت بايثون متكامل لكتابة مقالات متوافقة مع SEO ونشرها تلقائياً
شاهد معي كيف بنيت هذا السكربت، هذا مثال من واقع عملي على مواقع قمت بإنشاء هذا السكربت لها بلغة بايثون. يمكنك بناء سكربت بايثون لكتابة مقالات متوافقة مع السيو عبر ثلاث خطوات أساسية: أولاً، استدعاء نموذج Claude ببرومبت مهيكل يضم الكلمة المفتاحية وقواعد H2/H3؛ ثانياً، توليد مخطط بيانات مفصل (JSON-LD Schema) للأسئلة الشائعة والـ Article؛ ثالثاً، رفع المقال كمسودة أو مقال منشور عبر WordPress REST API باستخدام Application Passwords.
راجع مقالنا عن ما هو Claude AI؟ شرح شامل للمبتدئين قبل البدء إذا لم تكن قد تعاملت مع واجهته البرمجية من قبل.
ركز معى ماذا فعلت خطوة بخطوة
1. المتطلبات الأساسية وإعداد البيئة البرمجية
قبل تشغيل السكربت، يلزم تثبيت المكتبات الرسمية الخاصة بالتعامل مع الـ API وطلب شبكات الويب، بالإضافة إلى إصدار Python 3.10+.
تثبيت المكتبات (requirements.txt):
قم بتثبيت الحزم المعتمدة عبر أمر pip:
pip install anthropic requests python-dotenv beautifulsoup4
2. الهيكلية الكاملة لسكربت البايثون (SEO Article Generator)
يتميز هذا السكربت بـ:
- توليد مقال بصيغة HTML يراعي العناوين الهيكلية (
<h2>,<h3>) واستراتيجية BLUF. - إخراج البيانات كـ JSON منظم (Structured Output) لفصل العنوان والمحتوى والأسئلة الشائعة عن بعضها.
- فحص جودة آلي قبل النشر (عدد الكلمات، الفقرة الافتتاحية، الأرقام المشبوهة).
- بناء JSON-LD Schema تلقائياً لدعم نتائج FAQ في محرك البحث.
- نشر آمن عبر WordPress REST API مع معالجة أخطاء صريحة.
import os
import json
import re
import time
import requests
import anthropic
from dotenv import load_dotenv
from bs4 import BeautifulSoup
from requests.auth import HTTPBasicAuth
load_dotenv()
client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
WP_URL = os.getenv("WP_URL")
WP_USERNAME = os.getenv("WP_USERNAME")
WP_APP_PASSWORD = os.getenv("WP_APP_PASSWORD")
def build_seo_prompt(keyword, audience, intent, min_words=2500, max_words=3500):
return f"""
الكلمة المفتاحية: {keyword}
الجمهور المستهدف: {audience}
نية البحث: {intent}
أنشئ مقالاً أصلياً ومفيداً باللغة العربية.
استخدم البنية التالية:
{{
"title": "عنوان المقال",
"content": "<p>...</p><h2>...</h2>...",
"faq": [
{{"question": "السؤال الأول", "answer": "الإجابة..."}}
],
"meta_description": "وصف مختصر للمقال"
}}
قواعد المحتوى:
- يبدأ content بفقرة تجيب عن نية البحث مباشرة (BLUF)، لا تقل عن 50 كلمة.
- طول المحتوى بين {min_words} و{max_words} كلمة تقريباً.
- استخدم HTML فقط داخل content: h2, h3, p, ul, ol, table, pre, code.
- لا تضف Schema داخل content؛ سيقوم Python ببنائه لاحقاً.
- لا تخترع إحصاءات أو أرقاماً غير موثقة.
- اجعل الأسئلة الشائعة مرتبطة مباشرة بموضوع المقال.
"""
def generate_article(keyword, audience, intent, retries=3):
system_prompt = """أنت محرر تقني متخصص في مقالات SEO باللغة العربية.
أرجع الناتج بصيغة JSON صالح فقط دائماً، بدون Markdown أو ``` أو أي نص خارج JSON."""
user_prompt = build_seo_prompt(keyword, audience, intent)
for attempt in range(retries):
try:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=8000,
system=system_prompt,
messages=[
{"role": "user", "content": user_prompt},
{"role": "assistant", "content": "{"}
]
)
return "{" + response.content[0].text
except anthropic.RateLimitError:
wait = (2 ** attempt) * 5
print(f"⚠️ Rate limit — إعادة المحاولة بعد {wait}s")
time.sleep(wait)
raise RuntimeError("فشل التوليد بعد عدة محاولات بسبب Rate Limits")
def parse_article_response(text):
cleaned = text.strip().removeprefix("```json").removeprefix("```").removesuffix("```").strip()
article = json.loads(cleaned)
required = ["title", "content", "faq", "meta_description"]
missing = [f for f in required if f not in article]
if missing:
raise ValueError(f"الاستجابة تفتقد الحقول التالية: {missing}")
return article
def count_words(html_text):
soup = BeautifulSoup(html_text, "html.parser")
text = soup.get_text(" ", strip=True)
return len(re.findall(r"\S+", text))
def get_first_paragraph(html_text):
soup = BeautifulSoup(html_text, "html.parser")
paragraph = soup.find("p")
return paragraph.get_text(" ", strip=True) if paragraph else ""
def check_quality(html_text, min_words=2500):
word_count = count_words(html_text)
first_paragraph = get_first_paragraph(html_text)
issues = []
if word_count < min_words:
issues.append(f"عدد الكلمات ({word_count}) أقل من الحد الأدنى المطلوب ({min_words}).")
if not first_paragraph:
issues.append("لا توجد فقرة افتتاحية في المقال.")
elif len(first_paragraph.split()) < 30:
issues.append("الفقرة الافتتاحية قصيرة وتحتاج إلى مراجعة تحريرية.")
suspicious_numbers = re.findall(r"\b\d{2,}%|\$\d+(?:\.\d+)?", html_text)
if suspicious_numbers:
issues.append("توجد أرقام أو نسب تحتاج إلى مراجعة مصدرية: " + ", ".join(suspicious_numbers))
return issues
def build_faq_schema(faq_pairs):
return json.dumps({
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": question,
"acceptedAnswer": {"@type": "Answer", "text": answer}
}
for question, answer in faq_pairs
]
}, ensure_ascii=False, indent=2)
def publish_to_wordpress(site_url, title, html_content, faq_schema_json, status="draft"):
endpoint = f"https://www.aicodesmart.com/wp-json/wp/v2/posts"
auth = HTTPBasicAuth(WP_USERNAME, WP_APP_PASSWORD)
full_content = html_content + f'\n\n<script type="application/ld+json">\n{faq_schema_json}\n</script>'
payload = {"title": title, "content": full_content, "status": status}
response = requests.post(endpoint, json=payload, auth=auth, timeout=30)
response.raise_for_status()
return response.json().get("link")
if __name__ == "__main__":
target_keyword = "سكربت بايثون كتابة مقالات متوافقة مع السيو"
audience = "مطورون ومسوقو محتوى مبتدئون في الأتمتة"
intent = "معرفة كيفية بناء سكربت أتمتة كامل لتوليد ونشر مقالات SEO"
print(f"🚀 جاري توليد المقال للكلمة المفتاحية: {target_keyword}...")
try:
raw_response = generate_article(target_keyword, audience, intent)
article = parse_article_response(raw_response)
issues = check_quality(article["content"])
if issues:
print("⚠️ المقال يحتاج مراجعة قبل النشر:")
for issue in issues:
print(f" - {issue}")
faq_pairs = [(item["question"], item["answer"]) for item in article["faq"]]
schema_json = build_faq_schema(faq_pairs)
link = publish_to_wordpress(
site_url=WP_URL,
title=article["title"],
html_content=article["content"],
faq_schema_json=schema_json,
status="draft"
)
print(f"✅ تم رفع المقال كمسودة بنجاح: {link}")
except Exception as e:
print(f"❌ حدث خطأ أثناء تنفيذ السكربت: {e}")
شرح السكربت خطوة بخطوة: كل دالة وهي بتعمل إيه بالظبط
قبل ما تنسخ الكود وتشغّله، خليني أشرحلك كل دالة بأسلوب مبسّط عشان تفهم منطق السكربت مش تحفظه بس — ده هيسهّل عليك تعديله لاحقاً حسب احتياجك.
build_seo_prompt() — الدالة دي بتبني نص التعليمات (الـ Prompt) اللي هيتبعت لـ Claude. فكّر فيها كأنك بتكتب بريف لمحرر بشري: بتديله الكلمة المفتاحية، الجمهور، ونية البحث، وبتحدد له بالظبط شكل الناتج اللي عايزه (JSON بحقول معينة). كل ما البريف ده كان دقيق ومفصل، كل ما جودة المقال الناتج كانت أعلى.
generate_article() — دي القلب النابض للسكربت. بتاخد الـ Prompt من الدالة اللي فاتت وترسله فعلياً لـ Claude API، وبتستنى الرد. لاحظ إن فيها حلقة for attempt in range(retries) — دي شبكة أمان: لو حصل ضغط على الـ API (Rate Limit)، السكربت مش هيفشل فوراً، هيستنى شوية ويحاول تاني، والوقت بيزيد كل مرة ((2 ** attempt) * 5) عشان ميضغطش على الـ API أكتر.
parse_article_response() — Claude بيرجع النص كـ string عادي، مش كائن Python جاهز. الدالة دي شغلتها إنها تحوّل النص ده لـ JSON فعلي تقدر تتعامل معاه (title, content, faq…)، وفي نفس الوقت بتتأكد إن كل الحقول المطلوبة موجودة. لو حقل ناقص، بتوقف السكربت فوراً بدل ما تكمل بمقال ناقص من غير ما حد يلاحظ.
check_quality() — دي “المحرر الآلي” بتاعك. بتفحص 3 حاجات أساسية: عدد الكلمات كفاية ولا لأ، الفقرة الأولى قوية وواضحة ولا مبتورة، وفيه أرقام أو نسب مشبوهة محتاجة مراجعة بشرية (زي “40% زيادة” من غير مصدر). أي مشكلة من دول بتتسجل كتحذير، مش بتوقف النشر، لأن القرار النهائي لازم يفضل بإيدك.
build_faq_schema() — الدالة دي بتاخد الأسئلة الشائعة اللي رجعت من Claude وتحولها لكود JSON-LD بالشكل اللي جوجل بتفهمه، عشان يظهر لك Rich Snippet (نتيجة FAQ الموسّعة) في نتائج البحث.
publish_to_wordpress() — آخر خطوة، بتاخد المقال الجاهز وتبعته لموقعك عبر WordPress REST API. لاحظ سطر response.raise_for_status() — ده مهم جداً، لأنه بيخلي السكربت “يصرخ” بخطأ واضح لو النشر فشل (زي مشكلة في كلمة المرور)، بدل ما يفضل شغال وهو فعلياً مبينشرش حاجة.
# نسخة سريعة قابلة للتشغيل المباشر - انسخها كاملة كما هي
import os
import json
import re
import time
import requests
import anthropic
from dotenv import load_dotenv
from bs4 import BeautifulSoup
from requests.auth import HTTPBasicAuth
load_dotenv()
client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
WP_URL = os.getenv("WP_URL")
WP_USERNAME = os.getenv("WP_USERNAME")
WP_APP_PASSWORD = os.getenv("WP_APP_PASSWORD")
# ... (باقي الكود كما هو موضح في القسم السابق)
💡 نصيحة سريعة: لو نسخت الكود وشغّلته ووصلتك رسالة خطأ، ارجع لجدول “ما لا يستطيع السكربت ضمانه” فوق — معظم الأخطاء الشائعة هنا بتكون في إعداد ملف
.envمش في منطق الكود نفسه.
من واقع التجربة: مشكلة الـ Tokens اللي واجهتني فعلياً
أثناء تشغيل السكربت على دفعة من 15 كلمة مفتاحية متتالية، واجهت مشكلة محسوسة في استهلاك الـ Tokens أسرع مما توقعت. كل مقال كان بياخد تقريباً بين 6000-7000 token في الاستجابة الواحدة (بسبب طول المحتوى العربي + بنية JSON + وسوم HTML)، وده معناه إن الفاتورة كانت بتزيد بمعدل أسرع من حساباتي الأولية اللي كانت مبنية على تقدير tokens بالإنجليزي مش العربي.
الحل اللي وصلت له كان في خطوتين:
الأولى، ضفت طباعة لـ response.usage.output_tokens بعد كل استدعاء ناجح، عشان أقدر أراقب الاستهلاك الفعلي لحظياً بدل ما أفاجأ في نهاية الشهر بالفاتورة.
والتانية، بدل ما أشغل الـ 15 كلمة مفتاحية دفعة واحدة، قسّمتهم لدفعات من 5 مقالات، وبعد كل دفعة كنت براجع الجودة يدوياً قبل ما أكمل — ده وفرلي فلوس فعلياً لأن بعض المقالات كانت محتاجة تعديل في الـ Prompt نفسه (زي تضييق نطاق الموضوع أكتر)، ولو كنت شغّلت الـ 15 كلمة كلهم بنفس الـ Prompt غير المضبوط، كنت هدفع تكلفة توليد مقالات هعيد كتابتها أصلاً.
الدرس المستفاد: راقب استهلاك الـ Tokens من أول تشغيلة، ومتفترضش إن التقديرات النظرية هتطابق الواقع، خصوصاً مع المحتوى العربي.
3.آلية ربط السكربت بـ WordPress REST API بأمان
لتفادي المشاكل الأمنية ومخاطر استخدام بروتوكول XML-RPC القديم، نعتمد على Application Passwords عبر WordPress REST API الرسمي:
- ادخل إلى لوحة تحكم WordPress -> أعضاء (Users) -> حسابك الشخصي (Profile).
- انزل إلى قسم كلمات مرور التطبيقات (Application Passwords).
- اكتب اسماً للتطبيق (مثل:
Python SEO Script) وانقر إضافة كلمة مرور جديدة للتطبيق. - انسخ كلمة المرور المكونة من 24 حرفاً واحفظها في متغير
WP_APP_PASSWORDداخل ملف.env، ولا تكتبها مباشرة داخل الكود أبداً، اتساقاً مع مبدأ حماية المفاتيح الموضح سابقاً.
4.أفضل الممارسات لتطبيق معايير E-E-A-T وتجنب عقوبات Google
من واقع عملى انصحك بشده ان تتبع هذه النصائح حتى تتجنب عقوبات Google بل وتتصدر مقالاتك محركات البحث فعند الاعتماد على الأتمتة لإنشاء المحتوى، يجب الالتزام بإرشادات Google Search Central:
- المراجعة البشرية (Human-in-the-loop): يُنصح دائماً برفع المقالات بصيغة
draft(مسودة) ليقوم المحرر بتدقيق الحقائق وإضافة التنسيقات والصور الداخلية.
- إضافة القيمة المضافة (Information Gain): احرص على أن يتضمن السكربت طلب تجارب عملية أو أكواد برمجية حقيقية لا توفرها المقالات المنافسة.
- تحسين التعامل مع Rate Limits: إذا كنت تسحب كلمات مفتاحية متعددة، استخدم
time.sleep()مع Exponential Backoff بين الطلبات لتجنب حظر الـ API.
من واقع التجربة: مشكلات حقيقية واجهتها وحلولها
عند تشغيل هذا السكربت فعلياً على عدة كلمات مفتاحية متتالية، واجهت ثلاث مشكلات لم تظهر إلا بعد التنفيذ الفعلي، وليس أثناء كتابة الكود نظرياً:
المشكلة الأولى: JSON مقطوع رغم رفع max_tokens
في التشغيلة الأولى بـ max_tokens=4096، توقفت الاستجابة في منتصف قسم الـ FAQ تقريباً وفشل json.loads() بخطأ Expecting ',' delimiter. السبب لم يكن في المنطق البرمجي، بل في طول المحتوى العربي نفسه — الكلمات العربية تستهلك tokens أكثر من الإنجليزية بشكل ملحوظ. الحل كان رفع max_tokens إلى 8000، ومراقبة response.usage.output_tokens في أول عشر تشغيلات للتأكد من عدم الاقتراب من الحد الأقصى.
المشكلة الثانية: أرقام Encoding عند النشر لـ WordPress
بعض المقالات كانت تحتوي أرقاماً إنجليزية أو رموزاً داخل <pre><code> (أمثلة أكواد داخل المقال)، وعند إرسالها عبر requests.post() كانت تظهر مشوهة أحياناً في محرر WordPress. الحل: التأكد من أن الـ payload بالكامل يُرسل بترميز UTF-8 صريح، وعدم الاعتماد على الترميز الافتراضي للمكتبة.
المشكلة الثالثة: النموذج يتجاهل حد min_words أحياناً
رغم تحديد “2500-3500 كلمة” صراحة في الـ prompt، بعض المقالات جاءت بـ 1800-2000 كلمة فقط. دالة check_quality() هي اللي كشفت المشكلة تلقائياً بدل ما تنشر المقال الناقص كمسودة نهائية بدون تنبيه. هذا بالضبط سبب وجود طبقة الفحص بعد التوليد، وليس الاعتماد على تعليمات الـ Prompt وحدها.
أسئلة شائعة حول سكربت بايثون كتابة مقالات متوافقة مع السيو
هل يحتاج السكربت اشتراكاً مدفوعاً في واجهة الذكاء الاصطناعي؟
نعم، معظم واجهات الذكاء الاصطناعي القوية تعمل بنظام الدفع حسب الاستخدام، وتكلفة المقال الواحد تعتمد على طول Prompt والمخرجات، لذا يُنصح بتقدير التكلفة قبل تشغيل السكربت على عدد كبير من المقالات دفعة واحدة.
هل يمكن استخدام السكربت مع منصة غير WordPress؟
نعم من حيث المبدأ، لأن جزء التوليد والفحص مستقل عن منصة النشر، لكن دالة النشر نفسها يجب إعادة كتابتها لتتوافق مع REST API الخاص بالمنصة البديلة.
كيف يتجنب السكربت تكرار المحتوى بين المقالات؟
عبر تمرير قائمة بعناوين المقالات المنشورة سابقاً ضمن الـ Prompt كسياق، وطلب صريح من النموذج بتجنب تكرار نفس الزوايا التحريرية المستخدمة من قبل.
هل النشر المباشر التلقائي (Publish) آمن دون مراجعة بشرية؟
لا يُنصح به كإعداد افتراضي، لأن فحوصات الجودة الآلية تكشف مشاكل بنيوية (طول، Schema، أرقام مشبوهة) لكنها لا تضمن الدقة الموضوعية الكاملة، لذا تبقى المراجعة البشرية قبل النشر النهائي خطوة ضرورية.
هل المقالات المولدة بالسكربتات متوافقة مع Google SEO؟
يمكن لسكربت Python أن يساعد في إنشاء مقالات وفق ممارسات SEO، لكنه لا يضمن توافق المقال مع Google أو تصدره نتائج البحث. جودة النتيجة تعتمد على قيمة المحتوى ودقته ومدى ملاءمته لنية البحث، وليس على استخدام Python أو الذكاء الاصطناعي بحد ذاته.
الطريقة الأكثر أمانًا هي استخدام السكربت كجزء من Workflow يمر بعدة مراحل: توليد المحتوى، فحص البنية والطول، مراجعة المعلومات والأرقام، إضافة الروابط الداخلية والبيانات المنظمة عند الحاجة، ثم إرسال المقال إلى WordPress كمسودة للمراجعة البشرية قبل النشر.
كما أن استخدام الذكاء الاصطناعي لا يعني تلقائيًا أن المحتوى مخالف لإرشادات Google؛ المشكلة تكون عندما تُستخدم الأتمتة لإنتاج كميات كبيرة من الصفحات منخفضة القيمة دون إضافة حقيقية للمستخدم. لذلك يجب أن يكون الهدف من السكربت تحسين عملية إعداد المحتوى وضبط جودته، وليس إنتاج أكبر عدد ممكن من المقالات.
كيف أستخدم Python لكتابة مقالات SEO؟
تبدأ العملية بتحديد الكلمة المفتاحية ونية البحث والجمهور المستهدف، ثم يستخدم Python واجهة API لنموذج ذكاء اصطناعي لإنشاء المقال وفق Prompt محدد.
بعد التوليد، يمكن للسكربت تنفيذ سلسلة من عمليات التحقق، مثل:
فحص عدد الكلمات.
التحقق من وجود فقرة افتتاحية واضحة.
فحص بنية HTML.
مراجعة الأرقام والنسب التي تحتاج إلى مصادر.
معالجة الأسئلة الشائعة والبيانات المنظمة.
اختيار الروابط الداخلية المناسبة من قاعدة بيانات المقالات الموجودة.
تجهيز العنوان والوصف والرابط الدائم.
إرسال المقال إلى WordPress كمسودة.
بهذه الطريقة لا يكون Python مجرد أداة لإرسال Prompt إلى نموذج الذكاء الاصطناعي، بل يصبح طبقة تحكم وتحقق بين النموذج ومنصة النشر.
ما أفضل مكتبات Python لكتابة مقالات SEO؟
لا توجد مكتبة واحدة مسؤولة عن كتابة مقالات SEO؛ عادةً تحتاج إلى مجموعة من المكتبات، وكل واحدة تؤدي وظيفة مختلفة:
المكتبة
الاستخدامanthropic
الاتصال بواجهة Claude APIopenai
الاتصال بواجهة OpenAI API عند استخدام نماذجهاrequests
إرسال طلبات HTTP إلى WordPress REST APIpython-dotenv
تحميل مفاتيح API من ملف .envbeautifulsoup4
تحليل HTML واستخراج النص والعناصرjson
التعامل مع Structured Output وJSON-LDre
تنفيذ عمليات بحث ومعالجة نصية بسيطة
ولا تحتاج إلى تثبيت json أو re باستخدام pip؛ فهما جزء من مكتبات Python القياسية. أما anthropic وrequests وpython-dotenv وbeautifulsoup4 فتُثبت حسب المكتبات التي يستخدمها السكربت.
هل يمكن نشر المقالات من Python إلى WordPress؟
نعم. يوفر WordPress REST API نقاط نهاية يمكن استخدامها لإنشاء المقالات وإرسال محتواها برمجيًا. يستطيع السكربت إرسال العنوان والمحتوى والحالة، ويمكنه أيضًا التعامل مع بيانات أخرى مثل الـslug والصورة البارزة عند بناء Workflow أكثر اكتمالًا.
أقرأ أيضاً
- الربح من الذكاء الاصطناعي للمبتدئين 2026: 8 طرق حقيقية
- كيف تحول فكرتك إلى تطبيق بالذكاء الاصطناعي بدون برمجة؟ أفضل أدوات Prompt-to-App في 2026.
- تصميم صور بالذكاء الاصطناعي 2026: دليلك الشامل لإبداع مجاني ومذهل!
- أفضل أدوات إنشاء الفيديو بالذكاء الاصطناعي 2026: مقارنة شاملة للأسعار والمميزات
- كيف تستعيد زيارات جوجل بعد ظهور AI Mode؟ حل مشكلة انخفاض زيارات جوجل في 2026
- افضل AI للبرمجة 2026 :مقارنة شاملة لأقوى أدوات الذكاء الاصطناعى للمطورين
- أفضل 50 أداة ذكاء اصطناعي مجانية 2026 (دليل شامل لأقوى أدوات AI)
- أفضل أدوات كتابة المحتوى بالذكاء الاصطناعي 2026: مقارنة وتجربة عملية
- أفضل أدوات الذكاء الاصطناعي المجانية 2026: أكثر من 15 أداة لزيادة الإنتاجية والربح
- أفضل 100 أمر أو برومبت prompts لتوليد الصورة
الخلاصة
الخطوة العملية الأولى هي بناء دالة check_quality() وربطها بمنطق إعادة المحاولة قبل أي تفكير في أتمتة النشر الكامل، لأن معظم مشاكل هذا النوع من السكربتات تظهر في مرحلة الفحص لا في مرحلة التوليد نفسها.
بعد التأكد من استقرار الفحص، الخطوة التالية المنطقية هي بناء قاعدة بيانات محلية بسيطة لعناوين مقالاتك المنشورة، لتغذية دالة الربط الداخلي بروابط حقيقية بدل تركها فارغة أو معتمدة على تخمين النموذج. ابدأ بدفعة تجريبية من 3 إلى 5 مقالات بحالة “مسودة” فقط، راجعها يدوياً، ثم وسّع النطاق تدريجياً بعد التأكد من ثبات الجودة.
بناء سكربت بايثون لكتابة مقالات متوافقة مع السيو يحتاج منك أن تفهم كل شئ قبل البدأ لذلك وضعت بين يديك الخطوات والبرومبت الذى يؤهلك لعمل أتمته توليد مقالى متوافق مع السيو.
اذاوجهت او مشكلة او كان عندك أى سؤال أو محتاج أن أراجع معك خطوة بخطوة بناء الاسكربت الخاص بك تواصل معى أو اكتب تعليق أسفل المقال.



