بنية HTML ومحدّدات CSS
افهم أشجار DOM واكتب محدّدات CSS لاستهداف العناصر.
بنية HTML ومحدّدات CSS درس مجاني في R Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في R Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة R Academy 4 دروس في المجموع.
شجرة DOM في HTML
تُنظَّم كل صفحة ويب على هيئة شجرة نموذج كائن المستند (DOM). تتداخل عناصر HTML بعضها داخل بعض، مُشكِّلةً تسلسلًا هرميًا من العناصر الأصلية والفرعية. ويتنقل استخراج البيانات من الويب عبر هذه الشجرة لاستخراج البيانات.
# HTML structure conceptually:
# <html>
# <body>
# <div class='container'>
# <h1 id='title'>Hello</h1>
# <p class='text'>World</p>
# </div>
# </body>
# </html>
# rvest lets us query this tree with CSS selectors
library(rvest)
html <- read_html('<div><h1>Title</h1><p class="info">Text</p></div>')
html_text(html_element(html, 'h1'))محدِّد CSS: المحدِّد حسب الوسم
يستهدف أبسط محدِّدات CSS العناصرَ حسب اسم الوسم. يؤدي استخدام p إلى تحديد جميع عناصر الفقرات، بينما يؤدي استخدام h1 إلى تحديد جميع العناوين من المستوى الأول.
library(rvest)
html <- read_html('
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
<h2>A heading</h2>
</div>
')
# Tag selector: selects all <p> elements
nodes <- html_elements(html, 'p')
html_text2(nodes)
# Returns: c('First paragraph', 'Second paragraph')محدِّد CSS: الفئة والمعرّف
استخدم .classname لتحديد العناصر حسب الفئة، واستخدم #idname لتحديد عنصر فريد حسب المعرّف. يمكن أن تظهر الفئات مرات عديدة، بينما ينبغي أن تكون المعرّفات فريدة في الصفحة.
library(rvest)
html <- read_html('
<div>
<p class="highlight">Important text</p>
<p class="normal">Regular text</p>
<span id="price">$9.99</span>
</div>
')
# Class selector (prefix with .)
html_text2(html_element(html, '.highlight'))
# ID selector (prefix with #)
html_text2(html_element(html, '#price'))محدِّدات العناصر السلفية والفرعية
يحدد div p أي عنصر p داخل عنصر div (على أي عمق). أما div > p فيحدد العناصر الفرعية المباشرة فقط. ويحدد h1 + p عنصر p الذي يلي مباشرةً عنصر h1 (العنصر الشقيق المجاور).
library(rvest)
html <- read_html('
<div class="outer">
<p>Direct child</p>
<section>
<p>Nested deeper</p>
</section>
</div>
')
# Descendant: both paragraphs
all_p <- html_elements(html, 'div p')
length(all_p) # 2
# Direct child only
direct_p <- html_elements(html, 'div.outer > p')
length(direct_p) # 1محدِّدات السمات
تتيح لك محدِّدات سمات CSS التصفيةَ حسب سمات HTML: يتحقق [attr] من وجود السمة، ويتحقق [attr='val'] من تطابق القيمة تمامًا، ويتحقق [attr*='val'] من احتواء القيمة على سلسلة فرعية.
library(rvest)
html <- read_html('
<div>
<a href="https://example.com">External</a>
<a href="/about">Internal</a>
<a>No href</a>
</div>
')
# Select only anchors that have an href attribute
with_href <- html_elements(html, 'a[href]')
length(with_href) # 2
# Select anchors with href starting with https
external <- html_elements(html, 'a[href^="https"]')
html_text2(external) # 'External'أساسيات XPath
يُعد XPath بديلًا لمحدِّدات CSS، وهو أقوى للاستعلامات المعقدة. في rvest، استخدم html_element(html, xpath='//tag'). ويعني //p أي عنصر p في أي موضع، بينما يمثّل /html/body/p مسارًا مطلقًا.
library(rvest)
html <- read_html('
<html><body>
<table>
<tr><td class="price">10.99</td></tr>
<tr><td class="price">5.50</td></tr>
</table>
</body></html>
')
# XPath: select all td with class price
nodes <- html_elements(html, xpath = '//td[@class="price"]')
html_text2(nodes)
# c('10.99', '5.50')
# XPath text() function
nodes2 <- html_elements(html, xpath = '//td[contains(@class,"price")]')
html_text2(nodes2)دمج المحدِّدات
يمكن دمج المحدِّدات لزيادة الدقة. يحدد div.card h2 عنصر h2 داخل عنصر div ذي الفئة card. وتفصل الفاصلة بين محدِّدات مستقلة متعددة: يحدد h1, h2, h3 مستويات العناوين الثلاثة كلها.
library(rvest)
html <- read_html('
<div class="card">
<h2>Card Title</h2>
<p class="desc">Description here</p>
<span class="price">$19</span>
</div>
<div class="footer">
<h2>Footer Heading</h2>
</div>
')
# Only h2 inside .card
card_h2 <- html_element(html, 'div.card h2')
html_text2(card_h2) # 'Card Title'
# Multiple selectors with comma
price_desc <- html_elements(html, '.price, .desc')
html_text2(price_desc)أداة SelectorGadget
SelectorGadget هو bookmarklet للمتصفح يساعدك على العثور على محدِّدات CSS تفاعليًا. انقر على العناصر التي تريدها (فتُظلَّل بالأخضر) والعناصر التي لا تريدها (فتُظلَّل بالأحمر)، وسيُنشئ تلقائيًا محدِّد CSS الأدنى اللازم.
# SelectorGadget workflow:
# 1. Open target page in Chrome/Firefox
# 2. Activate SelectorGadget bookmarklet
# 3. Click element you want -> turns green, selector appears
# 4. Click elements you DON'T want -> turns red, selector narrows
# 5. Copy the selector shown at the bottom
# 6. Use in rvest:
library(rvest)
# Example: SelectorGadget found '.product-title' for us
# page <- read_html('https://books.toscrape.com')
# titles <- html_elements(page, '.product_pod h3 a')
# html_text2(titles)
cat('SelectorGadget is available at selectorgadget.com')فحص الصفحات في DevTools
تتيح لك أدوات DevTools في المتصفح (F12) فحص DOM مباشرةً. انقر بزر الفأرة الأيمن على أي عنصر، واختر Inspect، وستعرض لوحة Elements شيفرة HTML. يؤدي تمرير المؤشر إلى إبراز العناصر في الصفحة، مما يساعدك على تحديد الوسم والفئة والمعرّف المطلوب استهدافها بدقة.
# DevTools workflow for finding selectors:
# 1. F12 -> Elements tab
# 2. Click the cursor icon (Inspector)
# 3. Click the element on the page
# 4. Right-click highlighted HTML -> Copy -> Copy selector
# 5. Paste selector into rvest
# The copied selector might look like:
# '#main > div.results > article:nth-child(1) > h3'
# Simplify it: usually '.results h3' works just as well
# Validate your selector in the Console with:
# document.querySelectorAll('.results h3')
library(rvest)
cat('Always verify selectors return the elements you expect')الفئات الزائفة وnth-child
تتيح لك فئات CSS الزائفة مثل :first-child و:last-child و:nth-child(n) تحديد العناصر استنادًا إلى موضعها داخل العنصر الأصلي، وهو أمر مفيد عندما تفتقر العناصر إلى فئات مميِّزة.
library(rvest)
html <- read_html('
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
</ul>
')
# First item
first <- html_element(html, 'li:first-child')
html_text2(first) # 'First'
# Third item
third <- html_element(html, 'li:nth-child(3)')
html_text2(third) # 'Third'
# Even items
evens <- html_elements(html, 'li:nth-child(even)')
html_text2(evens) # c('Second', 'Fourth')قواعد أولوية المحدِّدات
عندما يمكن لعدة محدِّدات المطابقة، تحدد الأولوية أيّها يسود. تتفوق المعرّفات على الفئات، وتتفوّق الفئات على الوسوم. تقل أهمية ذلك في استخراج البيانات، لكن معرفة الأولوية تساعدك على كتابة محدِّدات دقيقة تتجنب المطابقات الخاطئة.
library(rvest)
html <- read_html('
<div id="header" class="top">
<p class="title">Main Title</p>
</div>
<div class="content">
<p class="title">Content Title</p>
</div>
')
# Overly broad: gets BOTH titles
broad <- html_elements(html, 'p.title')
html_text2(broad)
# Specific: only header title
specific <- html_element(html, '#header p.title')
html_text2(specific) # 'Main Title'
# Be as specific as needed but not more
content_title <- html_element(html, '.content .title')
html_text2(content_title)اختبار سريع
اختبروا مدى فهمكم لمحدِّدات CSS المستخدمة في كشط الويب باستخدام rvest.
مراجعة: محدِّدات HTML وCSS
أهم النقاط: شجرة DOM هي بنية شجرية، وتتنقّل فيها محدِّدات CSS. استخدموا tag لتحديد نوع العنصر، و.class لتحديد الفئة، و#id للعناصر الفريدة، و> للعناصر الابنة المباشرة، و[attr] للسمات. تساعدكم أداتا SelectorGadget وDevTools في اكتشاف المحدِّدات تفاعليًا. ويتعامل XPath (//tag[@attr]) مع الحالات التي لا تكفي فيها محدِّدات CSS.
# Summary of key CSS selectors for web scraping:
# 'p' -> all <p> elements
# '.price' -> elements with class='price'
# '#main' -> element with id='main'
# 'div > p' -> direct child p of div
# 'a[href]' -> a elements that have href attr
# 'a[href*=http] -> a elements where href contains 'http'
# 'li:nth-child(2)' -> second li in its parent
# 'h1, h2' -> both h1 and h2 elements
# xpath='//td[@class="price"]' -> XPath alternative
library(rvest)
cat('Selectors are the foundation of reliable web scraping')الأسئلة الشائعة
هل درس «بنية HTML ومحدّدات CSS» مجاني؟
نعم — نص درس «بنية HTML ومحدّدات CSS» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة R Academy، انتقل إلى CoddyKit PRO. تتضمن دورة R Academy 4 دروس في المجموع.
ماذا ستتعلم في «بنية HTML ومحدّدات CSS»؟
افهم أشجار DOM واكتب محدّدات CSS لاستهداف العناصر. تتمرن على R Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ R Academy؟
لا تُشترط خبرة سابقة. R Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «بنية HTML ومحدّدات CSS»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس R Academy هذا؟
نعم. كل درس في R Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- بنية HTML ومحدّدات CSS
- أساسيات html_element() وhtml_text()
- كشط الجداول والروابط
- التعامل مع تقسيم الصفحات والصفحات المتعددة