DOM یا Document Object Model به ساختار سلسله مراتبی و رابطه میان تگ های html درون یک صفحه اشاره دارد. در این ساختار سلسله مراتبی که به صورت یک درخت واره (tree) است، هر یک از تگ های درون صفحه به عنوان یک گره از  این ساختار درخت واره (tree) خواهند بود.

ریشه این درخت تگ html است و که خودش دارای دو زیر گره (گره فرزند) به نام head و body است که خود این گره های فرزند دارای گره های فرزند خودشان هستند که اصطلاحا یک رابطه والدفرزندی (parent-children) میان آنها به وجود می آید. شکل زیر نمونه ساده ای از ساختار  درخت واره را نشان می دهد.

ماژول bs4 دارای تعدادی متد است که از آن می توانیم از آنها برای جستجو در این ساختار درختی از تگ ها استفاده کنیم. پیش از این توسط خصوصیت title از کلاس BeautifulSoup به محتوای تگ title از html دسترسی داشتیم. چون DOM یک ساختار سلسله مراتبی است، پس می توانیم مابقی تگ ها را به نام آنها و به صورت مثال های نمونه زیر دنبال کنیم.

در کد بالا در واقع چون تنها تگ title درون تگ head قرار دارد، پس می توانیم با دنبال کردن بخشی از درختواره DOM از head به title برسیم. حال فرض کنید اولین و دومین تگ link را از درون بخش head می خواهید، پس باید مطابق دو کد زیر به ترتیب به اولین و دومین تگ link درون بخش head دسترسی پیدا کنید.

اما مطابق شکل زیر می بینید که مقدار برگشتی و ذخیره شده در سومین کد برابر با None است و به این معنی است که هیچ تگی با این مشخصه پیدا نشده است. بنابراین می توانیم نتیجه بگیریم که استفاده از خصوصیت هایی مانند title یا link یا img و جدا کردن آنها با نقطه به معنی پیمایش درختواره DOM به صورت والد-فرزندی است. به طور مثال مفهوم soup.head.title به معنی جستجو برای پیدا کردن تگ title که درون تگ head قرار دارد. soup.head.link.link به معنی جستجو برای تگ link که فرزند تگ link دیگر و خود این link فرزند تگ head قرار دارد و می دانید که چنین چیزی در html نیست.

توجه کنید منظور از تگ فرزند، آن تگ یا تگ هایی است که درون یک تگ دیگر قرار دارند. به طور مثال تگ های meta و link و title و script درون تگ head قرار دارند و خود تگ head درون تگ html قرار دارند، پس می توانیم برای رسیدن به تگ title از دستور زیر نیز استفاده کنیم. همینطور تگ هایی مانند div یا a درون تگ body قرار دارند و خود تگ body نیز در تگ html قرار دارد. در شکل اول از همین مطلب می توانید این ساختار والد-فرزندی و درختواره را ببینید.

بنابراین می توانیم از ساختار والد-فرزندی و درختواره DOM برای دستیابی به یک یا چندین تگ دلخواه استفاده کنیم. اما توجه کنید این روش استفاده از نام خصوصیت هایی همنام با نام تگ ها و جدا کردن آنها با نقطه کاربرد چندانی ندارد به این دلیل که ما یکباره تمامی تگ ها img را می خواهیم که درون یک تگ div با class به نام gallery وجود دارند در این حالت دو مورد زیر بوجود می آیند که توسط متدهای آموزش داده شده در مطلب های پیش رو این دو مورد را پوشش می دهیم:

۱ – چگونه تمامی تگ های خاص مانند تمامی تگ های p را بدست آوریم.

۲ – چگونه تمامی تگ های خاص با یک شناسه یا یک class مشابه را بدست آوریم.

در شکل زیر که بخشی از کدهای html صفحه https://python.org را نشان می دهد، می خواهیم محتوای (متن) اولین تگ strong درون تگ p را که درون  تگ div قرار دارد و خود این تگ div درون تگ div دیگر قرار دارد را نشان دهیم. چون می خواهیم متن را نشان دهیم، پس باید نهایتا از خصوصیت string استفاده کنیم تا متن میان تگ strong نشان داده شود. دستور زیر چگونگی انجام آنرا نشان می دهد. توجه کنید در دستورهای زیر، در واقع اولین خصوصیت div اشاره به اولین تگ div درون تگ body دارد و از همین رو دومین خصوصیت div به اولین تگ div درون (فرزند) div قبلی (والد) اشاره دارد.

دانلود سورس برنامه این مطلب web_scraping_with_python_and_bs4.ipynb

متدهای find در bs4 برای پیدا کردن تگ

اسکرپ کردن جدول ویکی پدیا با findAll و find_all