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

Тегҳо ва матн

Чаро HTML-ро таҳлил мекунем

Дар саҳифаи хабар сарлавҳаҳо, меню ва матни асосӣ бо нишонагузорӣ омехтаанд. Барнома бояд мундариҷаро аз ороиш фарқ кунад: масалан, номи бахшҳоро барои ҷустуҷӯ ҷамъ намояд. Parsing таҳлили ҳуҷҷат аз рӯйи сохтори он аст. Мо ба ҷойи ҷустуҷӯи мувофиқатҳои тасодуфии сатр унсурҳои зарурии дарахтро интихоб мекунем.

HTML аз тегҳо иборат аст: <p> банд, <b> ҷудокунии матн ва <a> пайвандро ифода мекунад. Тегҳои кушоянда ва пӯшанда мундариҷаро иҳота мекунанд. Дар дохили як унсур унсурҳои дигар ҷой гирифта метавонанд. BeautifulSoup сатри HTML-ро ба объектҳои Python табдил медиҳад, ки бо ҳар кадом алоҳида кор мекунем.

1. Сохтани дарахт

Таҳлилгар (parser) нишонагузориро хонда, ҷойгиршавии унсурҳоро дар дохили ҳам муайян мекунад. html.parser ба Python дохил аст. Аргументи якуми BeautifulSoup сатри тайёри HTML ва дуюм номи таҳлилгар аст. Ҳар мисоли зер алоҳида иҷро мешавад. Дар ин ҷо нишонаҳои омӯзишии A, B, C истифода мешаванд.

from bs4 import BeautifulSoup

html = "<section><p>A <b>B</b></p><p>C</p></section>"
soup = BeautifulSoup(html, "html.parser")
print(soup.section.name)
print(soup.b.get_text())

Натиҷа:

section
B

Объекти soup тамоми ҳуҷҷатро ифода мекунад, унсури ёфтшуда бошад, объекти Tag аст. Тег ном, мундариҷа ва методҳои ҷустуҷӯ дорад. BeautifulSoup худ саҳифаҳоро бор намекунад ва JavaScript-ро иҷро намекунад. Дар курс HTML аз вуруди стандартӣ меояд; тамоми онро бо sys.stdin.read() мехонанд, на бо як input().

2. Як натиҷа ё рӯйхат

find теги мувофиқи якумро медиҳад, ё агар чизе ёфт нашавад, None бармегардонад. find_all рӯйхати ҳамаи мувофиқатҳоро бо тартиби ҳуҷҷат медиҳад; ҳангоми набудани мувофиқат рӯйхат холӣ аст. Бо рӯйхати номҳо якчанд навъи тегро якбора ҷустуҷӯ кардан мумкин аст.

from bs4 import BeautifulSoup

soup = BeautifulSoup("<p>A</p><h4>B</h4><p>C</p>", "html.parser")
print(soup.find("p").get_text())
print([tag.name for tag in soup.find_all(["p", "h4"])])
print(soup.find("table"))
print(soup.find_all("table"))

Натиҷа:

A
['p', 'h4', 'p']
None
[]

3. Нишонагузорӣ ва матн

Чопи худи тег HTML-ро нишон медиҳад. Методи get_text() матни ҳамаи наслҳои онро бе тегҳо ҷамъ мекунад. Он байни калимаҳо фосилаи нав намесозад: аломатҳои дар ҳуҷҷат бударо мегирад. Хосияти .text ҳамон матнро медиҳад, вале ба метод параметр додан қулайтар аст.

from bs4 import BeautifulSoup

p = BeautifulSoup("<p>A <b>B</b> C</p>", "html.parser").p
print(p)
print(p.get_text())
print(p.b.get_text())

Натиҷа:

<p>A <b>B</b> C</p>
A B C
B

4. Фосилаҳо: ду амали гуногун

get_text().strip() аввал порчаҳои аслиро мепайвандад ва баъд фосилаҳоро танҳо аз ду канори натиҷа мебардорад. get_text(strip=True) ҳар порчаро алоҳида пок карда, бе ҷудокунак мепайвандад. Параметри separator ҷудокунакро ошкоро медиҳад. Интихоб ба масъала вобаста аст: фосилаи байни порчаҳо барои рӯйхати калимаҳо фоида дорад, вале пеш аз вергул метавонад зиёдатӣ бошад.

from bs4 import BeautifulSoup

p = BeautifulSoup("<p> A <b>B</b> C </p>", "html.parser").p
print(repr(p.get_text().strip()))
print(repr(p.get_text(strip=True)))
print(repr(p.get_text(" ", strip=True)))

Натиҷа:

'A B C'
'ABC'
'A B C'

5. Ҷустуҷӯ дар дохили блок

Теги ёфтшуда мисли soup методҳои ҷустуҷӯ дорад. Маҳдуд кардани ҳудуди ҷустуҷӯ маълумоти қисмҳои гуногуни саҳифаро омехта намекунад. Агар матн ададро ифода кунад, Python онро табдил медиҳад: int барои адади бутун ва float барои касрӣ. Худи BeautifulSoup сатр медиҳад.

from bs4 import BeautifulSoup

html = "<aside><em>99</em></aside><section><em> 12 </em><em>18</em></section>"
soup = BeautifulSoup(html, "html.parser")
block = soup.find("section")
values = [int(tag.get_text()) for tag in block.find_all("em")]
print(values)
print(max(values) - min(values))

Натиҷа:

[12, 18]
6

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

Ҷузвдонҳо ва файлҳои дохили онҳоро тасаввур кунед. Таҳлилгар барои ҳар тег гиреҳ ва барои мундариҷааш гиреҳҳои матнӣ месозад. Ҷустуҷӯ аз soup тамоми дарахтро ва аз block танҳо шохаи онро мегардад. find_all-и одӣ дар ҳар чуқурӣ меҷӯяд. find метавонад дар мувофиқати якум истад. get_text гиреҳҳои матнии шохаи интихобшударо мегардад ва мепайвандад. Сатри аслии HTML аз ин амалҳо тағйир намеёбад.

Номи тегҳои HTML ба шакли ягона оварда мешавад: <P> бо номи p ёфт мешавад. Таҳлилгар баъзе хатоҳои нишонагузориро таҳаммул мекунад, вале таҳлилгарҳои гуногун HTML-и нодурустро гуногун ислоҳ мекунанд. Барои такроршавии натиҷа html.parser-ро ошкоро диҳед.

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

1. Даъвати методи теги мавҷуднабуда. Агар nav набошад, soup.find("nav").get_text() хатои AttributeError медиҳад. Аввал натиҷаро санҷед. Дар мисол навъи хато қасдан нишон дода мешавад ва баъд санҷиши дуруст иҷро мегардад.

from bs4 import BeautifulSoup

soup = BeautifulSoup("<p>A</p>", "html.parser")
try:
    print(soup.find("nav").get_text())
except AttributeError as error:
    print(type(error).__name__)
tag = soup.find("nav")
print(tag is None)

Натиҷа:

AttributeError
True

2. .string-ро матни пурраи ҳар тег ҳисобидан. Ҳангоми чанд гиреҳи фарзанд он None аст. Агар танҳо як фарзанд-тег бошад, .string метавонад сатри ягонаи онро рекурсивӣ гирад. Пас қоидаи «теги дохилӣ ҳамеша None медиҳад» нодуруст аст. Барои ҳолати умумӣ get_text()-ро истифода баред.

from bs4 import BeautifulSoup

soup = BeautifulSoup("<p>A <b>B</b></p><div><b>C</b></div>", "html.parser")
print(soup.p.string)
print(soup.div.string)
print(soup.p.get_text())

Натиҷа:

None
C
A B

3. Интизор шудан, ки strip=True фосила илова мекунад. Дар мисоли боло ABC ҳосил шуд. Барои нигоҳ доштани фосилаҳои дохилӣ get_text().strip() ва барои гузоштани ҷудокунак байни порчаҳо get_text(" ", strip=True)-ро гиред.

4. Ҷамъ кардани сатрҳо ҳамчун адад. Амали + сатрҳоро мечаспонад. Пеш аз ҳисоб ҳар қиматро табдил диҳед.

from bs4 import BeautifulSoup

soup = BeautifulSoup("<i>12</i><i>18</i>", "html.parser")
a, b = [tag.get_text() for tag in soup.find_all("i")]
print(a + b)
print(int(a) + int(b))

Натиҷа:

1218
30

Ёддошт

  • BeautifulSoup(html, "html.parser") — таҳлили сатри HTML.
  • find("p") — теги якум ё None; find_all("p") — рӯйхат.
  • tag.find_all(...) — ҷустуҷӯ танҳо дар блоки интихобшуда.
  • str(tag) — HTML; tag.get_text() — матни наслҳо.
  • .get_text().strip() — бардоштани фосилаҳои канори матни умумӣ.
  • .get_text(" ", strip=True) — пок кардани порчаҳо ва пайвастан бо фосила.
  • .string ба сохтор вобаста аст; int(text) ададро табдил медиҳад.