0Pricing
R Academy · درس

أساسيات html_element() وhtml_text()

استخرج النص والسمات وبيانات الجداول من الصفحات التي جرى كشطها.

أساسيات html_element() وhtml_text() درس مجاني في R Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في R Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة R Academy 4 دروس في المجموع.

read_html(): تحميل صفحة

تُعدّ read_html() نقطة الدخول إلى rvest. مرّروا إليها عنوان URL أو سلسلة HTML خامًا. وتعيد كائنًا من النوع xml_document يمثّل شجرة DOM التي جرى تحليلها، ويكون جاهزًا للاستعلام.

library(rvest)

# From a URL (requires internet connection)
# page <- read_html('https://books.toscrape.com')

# From a raw HTML string (great for testing)
page <- read_html('
  <html><body>
    <h1>Book Store</h1>
    <p class="desc">Over 1000 books!</p>
  </body></html>
')
class(page)  # 'xml_document' 'xml_node'

html_element() مقابل html_elements()

تعيد html_element() العقدة الأولى المطابقة (أو NA إذا لم تُعثر على أي عقدة). أما html_elements() فتعيد جميع العقد المطابقة في قائمة. استخدموا الصيغة المفردة عندما تتوقعون نتيجة واحدة تحديدًا، والصيغة الجمع عند كشط القوائم.

library(rvest)
page <- read_html('
  <ul>
    <li class="item">Apple</li>
    <li class="item">Banana</li>
    <li class="item">Cherry</li>
  </ul>
')
# Singular: gets first match
first_item <- html_element(page, '.item')
html_text2(first_item)  # 'Apple'

# Plural: gets all matches
all_items <- html_elements(page, '.item')
html_text2(all_items)  # c('Apple', 'Banana', 'Cherry')
length(all_items)  # 3

html_text2() للحصول على نص منظّف

تستخرج html_text2() محتوى النص من العقد، فتزيل وسوم HTML وتدمج المسافات البيضاء بطريقة منظّمة. كما تتعامل مع <br> باعتباره فواصل أسطر. أما html_text() الأقدم فهي أقل ذكاءً في التعامل مع المسافات البيضاء.

library(rvest)
page <- read_html('
  <div class="product">
    <h2>  Laptop  </h2>
    <p>Price: <strong>$999</strong></p>
    <p>  Free   shipping  </p>
  </div>
')
# html_text2 trims whitespace intelligently
title <- html_element(page, 'h2')
html_text2(title)  # 'Laptop' (no extra spaces)

# From the whole div - collapses nested text
div <- html_element(page, '.product')
html_text2(div)  # 'Laptop\nPrice: $999\nFree shipping'

html_attr(): استخراج السمات

تستخرج html_attr(node, 'attr_name') قيمة سمة HTML. وهذا ضروري للحصول على href من الروابط، وsrc من الصور، وسمات data-*، وغير ذلك.

library(rvest)
page <- read_html('
  <div>
    <a href="https://example.com" title="Example site">Visit</a>
    <img src="/images/photo.jpg" alt="A photo">
    <div data-price="29.99">Product</div>
  </div>
')
# Extract href from link
link <- html_element(page, 'a')
html_attr(link, 'href')  # 'https://example.com'
html_attr(link, 'title')  # 'Example site'

# Extract src from image
img <- html_element(page, 'img')
html_attr(img, 'src')  # '/images/photo.jpg'

# Extract data attributes
div <- html_element(page, 'div[data-price]')
html_attr(div, 'data-price')  # '29.99'

html_attrs(): جميع السمات

تعيد html_attrs(node) متجهًا محرفيًا مُسمّى يضم جميع سمات العقدة. يفيد ذلك عندما لا تعرفون أسماء السمات مسبقًا، أو عندما تريدون فحص السمات المتاحة لعنصر ما.

library(rvest)
page <- read_html('
  <a href="/page" class="nav-link" id="home" data-section="main">Home</a>
')
link <- html_element(page, 'a')

# Get all attributes at once
attrs <- html_attrs(link)
attrs
# href        class        id           data-section
# '/page'     'nav-link'   'home'       'main'

# Access by name
attrs['href']   # '/page'
attrs['class']  # 'nav-link'
names(attrs)    # all attribute names

html_children(): العقد الابنة

تعيد html_children(node) العقد الابنة المباشرة لعنصر ما. وبدمجها مع html_name() للحصول على أسماء الوسوم، تصبح مفيدة لفهم بنية الصفحة برمجيًا.

library(rvest)
page <- read_html('
  <nav>
    <a href="/">Home</a>
    <a href="/about">About</a>
    <span>|</span>
    <a href="/contact">Contact</a>
  </nav>
')
nav <- html_element(page, 'nav')

# Get all direct children
kids <- html_children(nav)
length(kids)  # 4

# Get tag names of children
html_name(kids)  # c('a', 'a', 'span', 'a')

# Filter to only anchor children
links <- kids[html_name(kids) == 'a']
html_text2(links)  # c('Home', 'About', 'Contact')

html_name(): أسماء الوسوم

تعيد html_name(node) اسم وسم العقدة في صورة سلسلة محارف بأحرف صغيرة (مثل 'div' و'p' و'a'). ويفيد ذلك في تصفية قوائم العقد بحسب نوع العنصر بعد استرجاعها.

library(rvest)
page <- read_html('
  <article>
    <h2>Title</h2>
    <p>First paragraph.</p>
    <img src="img.jpg">
    <p>Second paragraph.</p>
  </article>
')
article <- html_element(page, 'article')
all_children <- html_children(article)

# Check tag name of each child
html_name(all_children)
# c('h2', 'p', 'img', 'p')

# Get only paragraph children
paras <- all_children[html_name(all_children) == 'p']
html_text2(paras)
# c('First paragraph.', 'Second paragraph.')

تسلسل التحديدات

يمكنكم تمرير عقدة (وليس المستند فقط) باعتبارها الوسيط الأول إلى html_element(). وبذلك يقتصر البحث على ما يقع داخل تلك العقدة، وهو أمر ضروري لكشط البنى المتكررة مثل بطاقات المنتجات أو صفوف الجداول.

library(rvest)
page <- read_html('
  <div class="card">
    <h3>Laptop</h3>
    <span class="price">$999</span>
  </div>
  <div class="card">
    <h3>Phone</h3>
    <span class="price">$499</span>
  </div>
')
# Get all cards, then extract fields from each
cards <- html_elements(page, '.card')

names_list <- html_text2(html_elements(page, '.card h3'))
prices_list <- html_text2(html_elements(page, '.card .price'))

data.frame(name = names_list, price = prices_list)

html_attr مع NodeSet

عند استدعائها على مجموعة عقد (ناتج html_elements())، تعيد html_attr() متجهًا من قيم السمات، قيمة واحدة لكل عقدة. وتعيد NA للسمات المفقودة.

library(rvest)
page <- read_html('
  <ul>
    <li><a href="/page1">Page 1</a></li>
    <li><a href="/page2">Page 2</a></li>
    <li><span>No link</span></li>
    <li><a href="/page3">Page 3</a></li>
  </ul>
')
# Get all a elements
links <- html_elements(page, 'a')

# html_attr on a nodeset returns a vector
hrefs <- html_attr(links, 'href')
hrefs  # c('/page1', '/page2', '/page3')

# Link text alongside hrefs
texts <- html_text2(links)
data.frame(text = texts, href = hrefs)

التعامل مع العناصر المفقودة

تعيد html_element() عقدة NA (وليس NULL) عندما لا تتطابق أي عقدة. ويعيد تطبيق html_text2() على عقدة NA القيمة NA_character_. تحقّقوا دائمًا من وجود NA في نتائجكم عندما تكون العناصر اختيارية.

library(rvest)
page <- read_html('
  <div class="product">
    <h3>Widget</h3>
    <!-- No price tag here -->
  </div>
')
# Element exists
title <- html_element(page, 'h3')
html_text2(title)  # 'Widget'

# Element does NOT exist -> NA node
price <- html_element(page, '.price')
html_text2(price)  # NA
is.na(html_text2(price))  # TRUE

# Safe extraction with default
price_text <- html_text2(price)
if (is.na(price_text)) price_text <- 'N/A'
price_text  # 'N/A'

جمع الأجزاء معًا

اجمعوا بين html_elements() وhtml_text2() وhtml_attr() لكشط بيانات منظّمة وتحويلها إلى إطار بيانات، وهو الهدف المعتاد من كشط الويب باستخدام rvest.

library(rvest)
page <- read_html('
  <div class="book">
    <a href="/book/1" class="title">R Programming</a>
    <span class="author">Hadley Wickham</span>
    <span class="rating" data-stars="5">*****</span>
  </div>
  <div class="book">
    <a href="/book/2" class="title">Advanced R</a>
    <span class="author">Hadley Wickham</span>
    <span class="rating" data-stars="5">*****</span>
  </div>
')
titles  <- html_text2(html_elements(page, '.title'))
authors <- html_text2(html_elements(page, '.author'))
links   <- html_attr(html_elements(page, 'a.title'), 'href')
ratings <- html_attr(html_elements(page, '.rating'), 'data-stars')
data.frame(title=titles, author=authors, link=links, stars=ratings)

اختبار سريع

اختبروا معرفتكم بالوظائف الأساسية في rvest للتنقّل في مستندات HTML.

مراجعة: الوظائف الأساسية في rvest

أهم النقاط: تحمّل read_html() الصفحات؛ وتحصل html_element() على أول تطابق؛ وتحصل html_elements() على جميع التطابقات. استخرجوا النص باستخدام html_text2()، والسمات باستخدام html_attr()، والعقد الابنة باستخدام html_children()، وأسماء الوسوم باستخدام html_name(). تعيد العناصر المفقودة عقد NA، لذا تعاملوا دائمًا مع NA في أدوات الكشط المستخدمة في بيئة الإنتاج.

library(rvest)
# Core rvest workflow:
# 1. Load page
# page <- read_html(url)

# 2. Find elements
# node  <- html_element(page, 'css-selector')
# nodes <- html_elements(page, 'css-selector')

# 3. Extract content
# html_text2(node)        -> text content
# html_attr(node, 'href') -> attribute value
# html_attrs(node)        -> all attributes
# html_name(node)         -> tag name
# html_children(node)     -> child nodes

# 4. Build data frame
# data.frame(title = html_text2(...), link = html_attr(...))
cat('rvest follows the tidy data philosophy')

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

هل درس «أساسيات html_element() وhtml_text()» مجاني؟

نعم — نص درس «أساسيات html_element() وhtml_text()» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة R Academy، انتقل إلى CoddyKit PRO. تتضمن دورة R Academy 4 دروس في المجموع.

ماذا ستتعلم في «أساسيات html_element() وhtml_text()»؟

استخرج النص والسمات وبيانات الجداول من الصفحات التي جرى كشطها. تتمرن على R Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ R Academy؟

لا تُشترط خبرة سابقة. R Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «أساسيات html_element() وhtml_text()»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس R Academy هذا؟

نعم. كل درس في R Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. بنية HTML ومحدّدات CSS
  2. أساسيات html_element() وhtml_text()
  3. كشط الجداول والروابط
  4. التعامل مع تقسيم الصفحات والصفحات المتعددة
← العودة إلى R Academy