1. Niyə find
və find_all
-dan istifadə etməliyik?
Bu gün biz HTML-dən elementləri effektiv və hədəfə yönəlmiş şəkildə çıxarmağa kömək edəcək iki əsas metod haqqında danışacağıq: find
və find_all
.
Koda başlamazdan əvvəl bu metodların ümumiyyətlə nə üçün lazım olduğunu müzakirə edək. Təsəvvür edin ki, veb səhifə böyük bir kitabxanadır və hər bir söz və cümlə HTML elementidir. Elə təsəvvür yaranır ki, lazım olan məlumatı tapmaq dondurmanın dadını bilmədən onun rəngini təxmin etməyə bənzəyir. find
və find_all
metodları sizin “dad detektorlarınız” kimi çıxış edir və lazımi məlumatı dəqiq müəyyən etməyə kömək edir.
find
: Bu metod proqramçıların səhər ilk fincan kofeni axtarmaq vərdişinə bənzəyir — tez bir zamanda tapır və verilən kriteriyalara uyğun gələn ilk elementi qaytarır.find_all
: Bu daha səbirli və əsaslı bir yanaşmadır, o, axtarış kriteriyalarına uyğun gələn bütün elementlərin siyahısını qaytarır. Bu, daha çox məlumat lazım olduğu hallarda (məsələn, gün ərzində bir neçə fincan qəhvə kimi) uyğundur.
2. find
metodunun istifadəsi
Beləliklə, find
metodu sizə birinci uyğun elementi sürətli şəkildə çıxarmağa kömək edir. Bu metod müxtəlif parametrlər qəbul edir, məsələn, tag adı, atributlar və hətta funksiyalar.
find
metodunun signaturası
find(name=None, attrs={}, recursive=True, string=None, **kwargs)
find
metodunun parametrləri
- name: Tapmaq istədiyiniz tagın adı. Bu hər hansı bir HTML tagı ola bilər, məsələn,
div
,p
,h1
,a
və s. - attrs: Tagın atributlarından ibarət dictionary. Məsələn,
{'class': 'example'}
və ya{'id': 'main'}
. Bu parametr axtarışı darlaşdırmağa kömək edir. - recursive: Boolean parametrdir ki, metodun bütün iç içə olan səviyyələrdə tagları axtarıb-axtarmayacağını müəyyən edir. Default olaraq
True
dəyərini götürür, bu isə bütün səviyyələrdə axtarış aparıldığı anlamına gəlir. - string: Müəyyən mətn ilə elementlərin axtarışı. Bu, məzmun mətninə görə elementləri süzmək üçün yararlıdır.
- kwargs: Atributlara görə axtarış üçün əlavə arqumentlər. Əgər
class_
kimi arqumentlər göstərilibsə, bunlarattrs={'class': 'value'}
kimi interpretasiya ediləcək.
Nümunə
from bs4 import BeautifulSoup
html_doc = """
<html>
<head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Bir zamanlar üç balaca bacı var idi; onların adları isə
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> və
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>
idi; və onlar quyunun dibində yaşayırdılar.</p>
</body>
</html>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
first_link = soup.find('a') # İlk <a> tagını tapırıq
print(first_link) # Çap edir: <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>
Gördüyünüz kimi, find
metodu sənəddəki ilk <a>
tagını tapdı və biz istədiyimiz məlumatın tapıldığına əmin olaraq axtarışımıza davam edirik.
3. find_all
metodunun istifadəsi
find_all
metodu göstərilən kriteriyalara uyğun olan bütün elementlərin siyahısını qaytarır. Bu metod, müəyyən bir növ tagları və ya müəyyən bir class ilə olan bütün elementləri tapmaq lazım olanda çox faydalıdır.
find_all
metodunun signaturası
find_all(name=None, attrs={}, recursive=True, string=None, limit=None, **kwargs)
find_all
metodunun parametrləri
- name: Tapmaq istədiyiniz tag-ın adı. Bu, tag-ın adı olan string (
div
,a
,p
və s.) və ya tag-ların siyahısı ola bilər, məsələn["div", "p"]
. - attrs: Tag-ları filtrasiya etmək üçün atributlar lüğəti, məsələn,
{'class': 'example'}
. - recursive: Axtarışın nested tag-ları da daxil olmaqla rekursiv edilib-edilməyəcəyini təyin edir. Varsayılan dəyər
True
. - string: Göstərilən mətni ehtiva edən tag-ları axtarır.
- limit: Qaytarılan nəticələrin maksimum sayını təyin edir. Əgər qeyd olunubsa, metod maksimum
limit
qədər element qaytaracaq. - kwargs: Tag atributlarını filtrasiya etmək üçün əlavə parametrlər.
find_all
-ın istifadəsinə nümunə
find
lazımi bir kitabı rəfdə tez axtarmağa bənzəyirsə, find_all
— bu daha detallı bir metoddur, məsələn, hər bir bölmə başlığını oxuyaraq araşdırmaq kimi.
all_links = soup.find_all('a') # Bütün <a> tag-larını tapırıq
for link in all_links:
print(link.get('href')) # Linkləri çap edir: http://example.com/elsie, http://example.com/lacie, http://example.com/tillie
Bu nümunədə biz bütün <a>
tag-larını tapırıq və hər birindən linkləri çıxarırıq. Bu, səhifədəki bütün linkləri toplamaq lazım olanda faydalıdır.
Əhəmiyyətli! find()
və find_all()
metodlarını yalnız soup obyektində deyil, həmçinin find()
, select()
və s. funksiyaların qaytardığı hər hansı bir uşaq elementdə də çağırmaq olar.
4. Elementləri filtrləmək üçün atributlardan istifadə
İndi isə məlumat aclığımızı idarə etdiyimizə görə, daha spesifik olmağın vaxtıdır. find
və find_all
metodları atributlar əsasında elementləri filtrləməyə imkan verir. Bu, qəhvə maşınında filtr quraşdırmaq kimi bir şeydir, tam sizin zövqünüzə uyğun içki əldə etmək üçün.
link_with_id = soup.find('a', id='link2') # id='link2' olan <a> tapırıq
print(link_with_id.text) # Çap edir: Lacie
id
parametrindən istifadə edərək lazımi elementi tez tapdıq. Eyni şəkildə, digər atributlardan, məsələn class
atributundan da istifadə edə bilərsiniz.
links_with_class = soup.find_all('a', class_='sister') # class='sister' olan bütün <a> tapırıq
for link in links_with_class:
print(link.get('id')) # Çap edir: link1, link2, link3
5. find
və find_all
müqayisəsi: hansını nə vaxt istifadə etməli?
Hər iki metodu bildiyinizdə, yəqin ki, belə bir sual yaranır: «Bəs find
nə vaxt, find_all
isə nə vaxt istifadə edilməlidir?» Məsələ sadədir. Əgər siz əminsinizsə ki, səhifədə yalnız bir element var və o sizə lazımdır, ya da sizi yalnız ilk tapılan element maraqlandırırsa, find
seçin. Lakin əgər sizə uyğun gələn bütün elementləri toplamaq lazımdırsa və onların sayı çox ola bilərsə, onda find_all
daha yaxşı seçimdir.
Parametr | find |
find_all |
---|---|---|
Qaytarılan dəyər | İlk tapılan element (ya da None , əgər tapılmadısa) |
Tapılan elementlərin siyahısı (ya da boş siyahı) |
Təyinat | Yalnız bir element lazımdırsa | Bütün uyğun elementləri almaq lazım olduqda |
limit parametri |
Tətbiq edilmir | Dəstəklənir: maksimum miqdarı təyin edir |
Müqayisə nümunəsi: Əgər səhifədəki bütün h2
başlıqlarını əldə etmək lazımdırsa, find_all
istifadə edin. Amma əgər sizə yalnız ilk h2
başlıq lazımdırsa, kifayət edir ki, find
istifadə edəsiniz.
# Səhifədəki bütün h2 başlıqlarını əldə et
all_h2_tags = soup.find_all("h2")
# Yalnız ilk h2 başlıq əldə et
first_h2_tag = soup.find("h2")
6. Praktiki tapşırıq
İndi nəzəriyyəni bildiyinizə görə, gəlin praktikada tətbiq edək. Bloqdan məqalələrin başlıqlarını və linklərini çıxaracaq kiçik bir skript hazırlayaq. Bunun üçün bütün başlıqları və linkləri tapmaq üçün find_all
istifadə edəcəyik, onların <h2>
teqində post-title
class-ı ilə olduğunu fərz edəcəyik.
blog_html = """
<html>
<body>
<h2 class="post-title"><a href="http://example.com/post1">Birinci Yazı</a></h2>
<h2 class="post-title"><a href="http://example.com/post2">İkinci Yazı</a></h2>
<h2 class="post-title"><a href="http://example.com/post3">Üçüncü Yazı</a></h2>
</body>
</html>
"""
blog_soup = BeautifulSoup(blog_html, 'html.parser')
post_titles = blog_soup.find_all('h2', class_='post-title')
for post in post_titles:
title = post.text
link = post.find('a')['href']
print(f"Başlıq: {title}, Link: {link}")
Əgər hər şey doğru edilibsə, aşağıdakıları görəcəksiniz:
Başlıq: Birinci Yazı, Link: http://example.com/post1
Başlıq: İkinci Yazı, Link: http://example.com/post2
Başlıq: Üçüncü Yazı, Link: http://example.com/post3
Diqqət edin ki, yuxarıdakı misalda find()
metodu post
obyektində çağırılır. Bu yolla artıq tapılmış elementin daxilində olan child elementləri axtarmaq mümkündür.
7. Tipik səhvlər
find
və find_all
ilə işləyərkən tez-tez səhvlər meydana gəlir. Məsələn, find
metodu elementi tapa bilməsə None
qaytarır ki, bu da AttributeError
-a səbəb ola bilər. Buna görə nəticəni istifadə etməzdən əvvəl hər zaman yoxlamaq lazımdır.
Eyni zamanda yanlış atributlarla bağlı problemlər də tez-tez rast gəlinir. Məsələn, atribut yazılarkən səhv edilərsə, metod heç bir şey tapa bilməyəcək. Buna görə tövsiyəm, HTML kodunda atributların düzgün yazıldığından hər zaman əmin olun.
GO TO FULL VERSION