Атрибутҳо ва пайвандҳо
Атрибутҳо барои чӣ лозиманд
Матни пайванд ба инсон мегӯяд, ки чӣ мебинад, атрибути href бошад, ба барнома суроғаи гузаришро медиҳад. Ҳамин тавр, src роҳи тасвир ва alt тавсифи матнии онро медиҳад. Ин маълумот барои ҷамъ кардани пайвандҳо, санҷидани дастрасии сомона ва интиқоли маълумот лозим аст.
Атрибут ҷуфти «ном ва арзиш» дар дохили теги кушоянда аст. Як тег метавонад якчанд атрибут дошта бошад, вале атрибути зарурӣ умуман набошад. Аз ин рӯ набудани арзиш, сатри холӣ ва матни ғайрихолиро фарқ кунед. Дар ҳамаи мисолҳо html.parser ошкоро интихоб шудааст.
1. Хондани арзиш
tag["href"] ба хондани луғат монанд аст. attrs ҳамаи атрибутҳоро нишон медиҳад ва has_attr мавҷудияти атрибути мушаххасро месанҷад. Ҳатто арзише, ки ба адад монанд аст, одатан сатр мебошад; табдилро алоҳида иҷро мекунанд.
from bs4 import BeautifulSoup
a = BeautifulSoup('<a href="/docs" data-count="8">A</a>', "html.parser").a
print(a["href"])
print(a.attrs)
print(a.has_attr("href"))
print(int(a["data-count"]) * 2)
Натиҷа:
/docs
{'href': '/docs', 'data-count': '8'}
True
16
2. Нест ё холӣ аст
Агар атрибут набошад, get("name") арзиши None медиҳад. Аргументи дуюм арзиши дигари пешфарзро медиҳад. Он танҳо ҳангоми набудани атрибут истифода мешавад: сатри холии мавҷуда холӣ мемонад. Барои атрибути бе арзиши ошкоро додашуда html.parser низ сатри холӣ нигоҳ медорад.
from bs4 import BeautifulSoup
soup = BeautifulSoup('<input disabled><img alt=""><a>A</a>', "html.parser")
print(soup.a.get("href"))
print(soup.a.get("href", "-"))
print(repr(soup.img.get("alt", "-")))
print(repr(soup.input["disabled"]))
Натиҷа:
None
-
''
''
3. Якчанд класс
class мансубияти унсурро ба гурӯҳҳо, масалан card ва wide, муайян мекунад. Дар ҳолати HTML BeautifulSoup ин атрибути чандарзишаро ба рӯйхат ҷудо мекунад. "card" in tag["class"] мавҷудияти як классро месанҷад. Баръакс, data-count сатри одӣ мемонад. Рафтори таҳлили XML метавонад фарқ кунад.
from bs4 import BeautifulSoup
div = BeautifulSoup('<div class="card wide" data-count="8"></div>', "html.parser").div
print(div["class"])
print("card" in div["class"])
print(type(div["data-count"]).__name__)
Натиҷа:
['card', 'wide']
True
str
4. Полоягӣ ҳангоми ҷустуҷӯ
href=True мавҷудияти атрибутро ифода мекунад, на ғайрихолӣ будани онро. Параметри class_ зерхат дорад, зеро class калимаи калидии Python аст. Он як классро дар байни чанд класс меҷӯяд. Барои номҳои дорои дефис ё ҳолатҳои махсус луғати attrs диҳед. Теги ёфтшударо баъд ба тарзи одӣ мехонед.
from bs4 import BeautifulSoup
html = '<a>A</a><a href="">B</a><a class="nav active" href="/x" data-zone="top">C</a>'
soup = BeautifulSoup(html, "html.parser")
print([a.get_text() for a in soup.find_all("a", href=True)])
print(soup.find("a", class_="nav")["href"])
print(soup.find(attrs={"data-zone": "top"}).get_text())
Натиҷа:
['B', 'C']
/x
C
5. Чӣ тавр URL-и нисбӣ ҳал мешавад
URL суроғаи манбаъ аст. Дар HTML он метавонад нисбӣ бошад: next.html файли ҷузвдони ҷорӣ, ../ як сатҳ боло ва / роҳи аз решаи сомона оғозшударо ифода мекунад. urljoin аз модули стандартии urllib.parse суроғаи саҳифа ва пайвандро аз рӯйи ҳамин қоидаҳо мепайвандад. Слеши охир муҳим аст: бе он қисми охирин одатан номи файл ҳисоб мешавад.
from urllib.parse import urljoin
page = "https://example.org/manual/start.html"
for href in ["next.html", "../help", "/login", "https://other.org/x", "//cdn.org/x"]:
print(urljoin(page, href))
print(urljoin("https://example.org/manual/", "next.html"))
print(urljoin("https://example.org/manual", "next.html"))
Натиҷа:
https://example.org/manual/next.html
https://example.org/help
https://example.org/login
https://other.org/x
https://cdn.org/x
https://example.org/manual/next.html
https://example.org/next.html
Дар дохил чӣ рӯй медиҳад
Таҳлилгар атрибутҳоро ҳангоми сохтани тег нигоҳ медорад, бинобар ин хондани attrs HTML-ро аз нав таҳлил намекунад. Баъзе атрибутҳои чандарзиша ба рӯйхат оварда мешаванд. Рамзҳои махсуси HTML дар арзиш кушода мешаванд: & ба & табдил меёбад.
urljoin бо сатрҳои суроға ҷудо аз BeautifulSoup кор мекунад. Он схема, номи сервер ва роҳро ба ҳисоб мегирад, вале дархости шабакавӣ намефиристад ва мавҷудияти саҳифаро намесанҷад. Суроғаи пурраи натиҷавӣ метавонад ба сомонаи дигар равад; худи ҳал кардани суроға доменҳоро полоя намекунад.
from bs4 import BeautifulSoup
a = BeautifulSoup('<a href="/search?a=1&b=2">A</a>', "html.parser").a
print(a["href"])
Натиҷа:
/search?a=1&b=2
Хатоҳои маъмул
1. Хондани атрибути ихтиёрӣ бо қавсҳои мураббаъ. Агар калид набошад, KeyError ҳосил мешавад. Барои арзиши ихтиёрӣ get-ро истифода баред; мисол хато ва хондани бехатарро нишон медиҳад.
from bs4 import BeautifulSoup
a = BeautifulSoup("<a>A</a>", "html.parser").a
try:
print(a["href"])
except KeyError as error:
print(type(error).__name__)
print(a.get("href", "-"))
Натиҷа:
KeyError
-
2. class-ро сатр ҳисобидан. Муқоисаи рӯйхат бо "card" натиҷаи False медиҳад. Мансубиятро санҷед ё бо class_ ҷустуҷӯ кунед.
3. Фосилаҳоро тавсифи муфид ҳисобидан. bool(" ") ба True баробар аст; аввал .strip()-ро даъват кунед. Арзиши пешфарзи get барои атрибути мавҷуднабуда қулай аст.
from bs4 import BeautifulSoup
img = BeautifulSoup('<img class="card wide" alt=" ">', "html.parser").img
print(img["class"] == "card", "card" in img["class"])
print(bool(img.get("alt", "")))
print(bool(img.get("alt", "").strip()))
Натиҷа:
False True
True
False
4. Пайвастани URL бо +. Барои роҳ аз реша чунин пайваст ҷузвдони зиёдатиро нигоҳ медорад. urljoin қоидаҳои URL-ро истифода мебарад, на қоидаҳои часпондани сатрҳоро. Баъд аз ҳал кардани суроғаҳо баъзан такрорҳоро алоҳида бардоштан лозим аст; агар тартиб муҳим бошад, онро ҳам нигоҳ доред.
from urllib.parse import urljoin
base = "https://example.org/manual/"
href = "/help"
print(base + href)
print(urljoin(base, href))
Натиҷа:
https://example.org/manual//help
https://example.org/help
Ёддошт
tag["href"]— атрибути ҳатмӣ; ҳангоми набуданKeyError.tag.get("href", "")— арзиш ё варианти эҳтиётии додашуда.tag.attrs,tag.has_attr("alt")— ҳамаи атрибутҳо ва санҷиши мавҷудият.tag["class"]— рӯйхати классҳо дар ҳолати HTML.find_all("a", href=True)— тегҳои дорои атрибут, ҳатто холӣ.class_="card",attrs={"data-zone": "top"}— полояҳо.urljoin(base, href)— ҳал кардани суроғаи нисбӣ бе истифодаи шабака.