Гузариш ба мундариҷа
Мавзӯи 3 аз 5

Интихобгарҳои CSS

Интихобгарҳои CSS барои чӣ лозиманд

Агар саҳифа блокҳои монанди зиёд дошта бошад, танҳо номи тег кофӣ нест. Шартҳо лозиманд: унсури дорои класси муайян, пайванд дар бахш ё сабти бе нишонаи хизматӣ. Интихобгари CSS тавсифи кӯтоҳи чунин шарт аст. Таҳиягарони веб ҳамин забонро барои ороиши саҳифа истифода мебаранд; дар BeautifulSoup он барои интихоби маълумот ёрӣ медиҳад.

Интихобгар чизеро тағйир намедиҳад ва намекашад: танҳо унсурҳои мувофиқи дарахти сохташударо меёбад. Пеш аз истифода дар тамоми саҳифа онро дар порчаи хурди HTML санҷидан мумкин аст. Ин махсусан вақте муфид аст, ки блокҳои зоҳиран монанд вазифаҳои гуногун доранд.

1. Унсури якум ва ҳамаи мувофиқатҳо

select рӯйхати тегҳоро бо тартиби ҳуҷҷат медиҳад. select_one теги якум ё None медиҳад. Барои ҷустуҷӯ дар блоки муайян ин методҳоро аз худи тег даъват кунед. Бар хилофи find, ба онҳо сатри CSS медиҳанд, на танҳо ном ва параметрҳои ҷудогона.

from bs4 import BeautifulSoup

soup = BeautifulSoup("<p>A</p><p>B</p>", "html.parser")
print([tag.get_text() for tag in soup.select("p")])
print(soup.select_one("p").get_text())
print(soup.select_one("table"))
print(soup.select("table"))

Натиҷа:

['A', 'B']
A
None
[]

2. Ном, класс ва id

p аз рӯйи номи тег, .note аз рӯйи класс ва #intro аз рӯйи id интихоб мекунад. Нуқта класси алоҳидаро ифода мекунад, пас .note ба class="note wide" ҳам мувофиқ аст. p.note ҳам теги p ва ҳам класси note-ро талаб мекунад. Якчанд нуқта, масалан .note.wide, ҳамаи классҳои зикршударо талаб мекунанд.

from bs4 import BeautifulSoup

html = '<p id="intro" class="note wide">A</p><div class="note">B</div><p>C</p>'
soup = BeautifulSoup(html, "html.parser")
for selector in [".note", "p.note", ".note.wide", "#intro"]:
    print(selector, [tag.get_text() for tag in soup.select(selector)])

Натиҷа:

.note ['A', 'B']
p.note ['A']
.note.wide ['A']
#intro ['A']

3. Ҷойгиршавии дохилӣ ва фарзанди бевосита

Фосила дар section a маънои пайванд дар дохили бахш дар ҳар чуқуриро дорад. Аломати > дар section > a волидайни бевоситаи section-ро талаб мекунад. Ин шарт барои ҳар унсур санҷида мешавад. Масалан, ul > li метавонад банди дохилиро ҳам гирад, агар волидайни худаш ul бошад. Барои маҳдуд кардан ба рӯйхати берунии мушаххас id-и онро диҳед.

from bs4 import BeautifulSoup

html = '<ul id="root"><li>A<ul><li>B</li></ul></li><li>C</li></ul>'
soup = BeautifulSoup(html, "html.parser")
print(len(soup.select("#root li")))
print(len(soup.select("#root > li")))
print(len(soup.select("ul > li")))

Натиҷа:

3
2
3

4. Шартҳо барои атрибутҳо

Қавсҳои мураббаъ атрибутро месанҷанд. [href] мавҷудият ва [target="_blank"] арзиши дақиқро талаб мекунад. Амали ^= оғози сатр ва $= анҷоми онро месанҷад. Атрибутҳои data-* маълумоти барномаро нигоҳ медоранд; баъд аз интихоб онҳоро бо калид мехонанд. Атрибути холӣ ҳам мавҷуд ҳисоб мешавад.

from bs4 import BeautifulSoup

html = '<a href="https://example.org" target="_blank">A</a><a href="/x">B</a><img src="x.png"><option selected>7</option>'
soup = BeautifulSoup(html, "html.parser")
print(len(soup.select("a[href]")))
print(soup.select_one('a[target="_blank"]').get_text())
print(len(soup.select('a[href^="https"]')))
print(soup.select_one('img[src$=".png"]')["src"])
print(soup.select_one("option[selected]").get_text())

Натиҷа:

2
A
1
x.png
7

5. Истисно ва якҷоякунӣ

:not(.hidden) унсурҳои дорои класси hidden-ро истисно мекунад. Вергул шартҳоро бо маънои «ё» мепайвандад ва тартиби ҳуҷҷатро нигоҳ медорад. Теги ба ду шарт мувофиқ дар рӯйхат такрор намешавад. Методҳои интихоб аз блоки ёфтшуда ҳам кор мекунанд, то маълумоти беруни он ба натиҷа надарояд.

from bs4 import BeautifulSoup

html = '<main><p class="note">A</p><p class="hidden">B</p><h4>C</h4></main><p>D</p>'
soup = BeautifulSoup(html, "html.parser")
block = soup.select_one("main")
print([tag.get_text() for tag in block.select("p:not(.hidden), h4")])
print(len(block.select("p, .note")))

Натиҷа:

['A', 'C']
2

Дар дохил чӣ рӯй медиҳад

BeautifulSoup шартҳои CSS-ро ба китобхонаи SoupSieve медиҳад. Он сатри интихобгарро таҳлил карда, муносибати гиреҳҳоро месанҷад: ном, классҳо, атрибутҳо ва волидайн. Ин ба полояи феҳрист монанд аст, ки чанд аломат бояд якбора иҷро шаванд. Интихобгар маънои «матни муфид» ё «нарх»-ро намедонад; ин маъноро сохтори саҳифа медиҳад.

Рӯйхати select объектҳои тегро дорад, на сатрҳоро. Баъд аз интихоб матн ё атрибутро алоҳида гиред ва агар лозим бошад, ададро табдил диҳед. Мисоли баъдӣ нишонаҳои намоёнро дар як блок интихоб мекунад; ин қадами ҷудогона пеш аз коркарди арзишҳост.

from bs4 import BeautifulSoup

html = '<div id="stats"><span class="value" data-n="4">A</span><span class="value hidden" data-n="9">B</span></div><span class="value" data-n="99">C</span>'
soup = BeautifulSoup(html, "html.parser")
tags = soup.select("#stats span.value:not(.hidden)")
print([(tag.get_text(), int(tag["data-n"])) for tag in tags])

Натиҷа:

[('A', 4)]

Хатоҳои маъмул

1. Нагузоштани нуқта пеш аз класс. select("note") теги <note>-ро меҷӯяд, на классро. .note дуруст аст.

2. Талаб кардани арзиши дақиқи тамоми class. [class="note"] ба class="note wide" мувофиқ нест. Барои класси алоҳида нуқтаро истифода баред. Мисоли баъдӣ ду дархости нодуруст ва як дурустро нишон медиҳад.

from bs4 import BeautifulSoup

soup = BeautifulSoup('<p class="note wide">A</p>', "html.parser")
print(len(soup.select("note")))
print(len(soup.select('[class="note"]')))
print(len(soup.select(".note")))

Натиҷа:

0
0
1

3. Омехтани .note.wide ва .note .wide. Якум ду классро дар як унсур талаб мекунад, дуюм бошад, як унсурро дар дохили дигар.

4. Гирифтани натиҷаи якум бе санҷиш. select метавонад рӯйхати холӣ диҳад ва [0] хатои IndexError меорад. Барои як унсури ихтиёрӣ select_one ва санҷиши None-ро истифода баред. Бо вуҷуди ин, сабаби холӣ будани интихобро бояд фаҳмед.

from bs4 import BeautifulSoup

soup = BeautifulSoup('<div class="note wide">A</div>', "html.parser")
print(len(soup.select(".note.wide")))
print(len(soup.select(".note .wide")))
try:
    print(soup.select("table")[0])
except IndexError as error:
    print(type(error).__name__)
print(soup.select_one("table") is None)

Натиҷа:

1
0
IndexError
True

Ёддошт

Навишт Маъно
select, select_one Рӯйхат; теги якум ё None
p, .note, #intro Номи тег, класс, id
p.note, .note.wide Шартҳо барои як унсур
A B, A > B Насл дар ҳар чуқурӣ; фарзанди бевосита
A, B Якҷоякунӣ бо тартиби ҳуҷҷат
[href], [target="_blank"] Мавҷудият; арзиши дақиқ
[href^="https"], [src$=".png"] Оғоз; анҷоми арзиш
:not(.hidden) Истисно