1. Mürəkkəb HTML-strukturlarla işləmənin əsasları
Mürəkkəb HTML-markupları təhlil etməyə başlamadan əvvəl, HTML-in nə üçün bu qədər dolaşıq ola biləcəyini anlamaq vacibdir. Veb inkişaf etdiricilər tez-tez kontenti təşkil etmək üçün mürəkkəb iç-içə elementlərdən istifadə edirlər ki, bu da belə səhifələrdən məlumatları çıxarmağa çalışanlar üçün əsl baş ağrısına çevrilə bilər. Amma narahat olmayın — yaxşı bir plan və alətlərlə siz asanlıqla öhdəsindən gələcəksiniz!
HTML ağacını başa düşmək
HTML sənədini ağac kimi təsəvvür edin: hər bir element — bir düyündür, o ya mətn ya da başqa düyünlərdən ibarət ola bilər. Bu ağacın zirvəsində html
durur, onun ardınca head
və body
gəlir, ondan sonra isə müxtəlif övlad elementlər yerləşir. İç-içə elementlər bu ağacın daha dərin qatlarındadır.
Sadə HTML-struktur nümunəsi:
<html>
<head>
<title>Nümunə</title>
</head>
<body>
<div class="content">
<h1>Başlıq</h1>
<p>Paraqraf 1</p>
<p>Paraqraf 2</p>
<div class="nested">
<ul>
<li>Element 1</li>
<li>Element 2</li>
<li><span>Element 3</span></li>
</ul>
</div>
</div>
</body>
</html>
Gördüyünüz kimi, bizim nested
class-ı ilə bir div
var, bu ul
-u ehtiva edir, o isə öz növbəsində li
ilə doludur. Bu, elementlərin necə iç-içə yerləşə biləcəyinə bir nümunədir.
2. BeautifulSoup
ilə məlumat çıxarışı
Nested elementlərdən məlumat çıxarışı
BeautifulSoup-un necə işlədiyini yada salırıq. Indi isə gəlin, BeautifulSoup-dan istifadə edərək li
siyahısından mətn çıxarışını edək. Detektiv rolunda özümüzü sınayırıq və nested strukturlarımızdan məlumat toplayırıq.
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
nested_items = soup.select('.nested ul li')
for item in nested_items:
print(item.get_text())
Nəticə:
Element 1
Element 2
Element 3
Gördüyünüz kimi, select
metodundan və CSS-selektordan istifadə edərək nested
sinifinə malik elementlərin içindəki bütün li
-ləri tapdıq. get_text()
metodu isə tapılan elementlərdən mətni birbaşa çıxarış etməyə imkan verir.
3. Çoxsəviyyəli elementlərlə iş
Bəzən məlumatlar təkcə strukturun dərinliyində yox, həm də müxtəlif səviyyələrdə bölünmüş şəkildə olur ki, bu da məlumatların çıxarılması işini daha da çətinləşdirir. Gəlin mürəkkəb bir HTML ağacından məlumat çıxarmağın yollarını anlayaq.
Mürəkkəb struktur nümunəsi:
<html>
<body>
<div class="wrapper">
<div class="header">
<h1>Bu başlıqdır</h1>
</div>
<div class="content">
<div class="article">
<h2>Məqalə 1</h2>
<p>Məqalə 1-in məzmunu</p>
</div>
<div class="article">
<h2>Məqalə 2</h2>
<p>Məqalə 2-nin məzmunu</p>
</div>
</div>
<div class="footer">
<p>Əlaqə məlumatı</p>
</div>
</div>
</body>
</html>
Səviyyələrdən məlumatların çıxarılması
İndi isə bütün məqalələrin adlarını və məzmunlarını çıxarmağa çalışaq.
articles = soup.select('.content .article')
for article in articles:
title = article.find('h2').get_text()
content = article.find('p').get_text()
print(f'Başlıq: {title}')
print(f'Məzmun: {content}\n')
Gözlənilən çıxış:
Başlıq: Məqalə 1
Məzmun: Məqalə 1-in məzmunu
Başlıq: Məqalə 2
Məzmun: Məqalə 2-nin məzmunu
Məqsədimizə çatmaq üçün select
və find
metodlarının birləşməsindən istifadə edirik. select
ana elementi tapmağa kömək edir, find
isə uşaq elementlərdən məlumatları çıxarır.
4. Daxili elementlərlə iş xüsusiyyətləri
Veb-səhifələrə baxarkən, eyni sinif və ya teqlərə malik bir neçə daxili elementlərin olması kimi problemlərlə qarşılaşa bilərsiniz. Belə hallarda, kontekstual axtarışdan istifadə və lazım olan elementlərin dəqiq müəyyənləşdirilməsi səhvlərdən qaçmağa kömək edəcək.
Mürəkkəb daxiletmə nümunəsi:
<html>
<body>
<div class="container">
<div class="item">
<h2>Nömrə 1</h2>
<div class="details">Detallar 1</div>
</div>
<div class="item">
<h2>Nömrə 2</h2>
<div class="details">Detallar 2</div>
<div class="additional">
<div class="info">Əlavə məlumat</div>
</div>
</div>
</div>
</body>
</html>
Daxiletmə nəzərə alınaraq məlumatların çıxarılması
Qarışıqlığın qarşısını almaq üçün daha spesifik elementləri tapmaq lazımdır:
items = soup.select('.container .item')
for item in items:
number = item.find('h2').get_text()
details = item.select_one('.details').get_text()
additional_info = item.select_one('.additional .info')
print(f'Nömrə: {number}')
print(f'Detallar: {details}')
if additional_info:
print(f'Əlavə məlumat: {additional_info.get_text()}')
print()
Burada, məlumatların əlavə bloklardan təkrarlanmasının qarşısını almaq üçün yalnız birinci tapılmış elementi qaytaran select_one
metodundan istifadə edirik.
5. Praktik aspektlər və tipik səhvlər
Mürəkkəb HTML-strukturlarla işləyərkən asanlıqla çaşqınlıq yaranır və ya səhvlərlə qarşılaşmaq mümkündür. Tipik səhvlərdən biri mövcud olmayan elementə giriş cəhdidir, bu da AttributeError
-a səbəb olur. Bunun qarşısını almaq üçün elementin mövcudluğunu yoxlamağı unutmayın, istifadə etməzdən əvvəl.
Digər bir vacib məsələ — hər zaman məlumatı dərhal "birbaşa" çıxarmanın lazım olmadığını başa düşməkdir. Bəzən strukturun ilkin təhlilini həyata keçirmək, debug çıxışlarından istifadə etmək və ara nəticələri yoxlamaq faydalı olur.
Real layihələrdə mürəkkəb HTML-strukturlarla iş bacarıqları olduqca vacib ola bilər. Bu bacarıqları yalnız web-scraping üçün deyil, həmçinin web interfeyslərin test edilməsi, avtomatlaşdırılmış testlərin yazılması və hətta mürəkkəb API-lərdən məlumatların təhlilində istifadə etmək mümkündür, xüsusilə formatlaşdırılmış, ikincili cavab olduqda.
GO TO FULL VERSION