آموزش درخت جستجو در Beautiful soup
آموزش درخت جستجو در Beautiful soup
در این درس از مجموعه آموزش برنامه نویسی سایت سورس باران، به آموزش درخت جستجو در Beautiful soup خواهیم پرداخت.
پیشنهاد ویژه : پکیج آموزش پروژه محور پایتون
متد های Beautifulsoup بسیاری وجود دارد که به ما امکان می دهد درخت تجزیه را جستجو کنیم. متداول ترین متد ها ()find و ()find_all هستند.
قبل از صحبت در مورد ()find و ()find_all ، اجازه دهید چند نمونه از فیلترهای مختلفی را که می توانید به این متد ها منتقل کنید، مشاهده کنیم.
انواع فیلترها
ما فیلترهای مختلفی داریم که می توانیم آنها را به این متد ها انتقال دهیم و درک این فیلترها بسیار مهم است زیرا این فیلترها بارها و بارها در طول API جستجو استفاده می شوند. ما می توانیم از این فیلترها بر اساس نام تگ، ویژگی های آن، متن یک رشته یا مخلوط اینها استفاده کنیم.
یک رشته
یکی از ساده ترین انواع فیلتر، رشته است. عبور یک رشته به متد جستجو و Beautifulsoup یک مسابقه با آن رشته دقیق انجام می دهد.
در زیر کد، همه تگ های <p> در سند را پیدا خواهید کرد –
1 2 3 |
>>> markup = BeautifulSoup('<p>Top Three</p><p><pre>Programming Languages are:</pre></p><p><b>Java, Python, Cplusplus</b></p>') >>> markup.find_all('p') [<p>Top Three</p>, <p></p>, <p><b>Java, Python, Cplusplus</b></p>] |
عبارت منظم
می توانید تمام تگ ها را با یک رشته / تگ مشخص شروع کنید. قبل از آن ما برای استفاده از عبارت منظم باید ماژول re را وارد کنیم.
1 2 3 4 5 |
>>> import re >>> markup = BeautifulSoup('<p>Top Three</p><p><pre>Programming Languages are:</pre></p><p><b>Java, Python, Cplusplus</b></p>') >>> >>> markup.find_all(re.compile('^p')) [<p>Top Three</p>, <p></p>, <pre>Programming Languages are:</pre>, <p><b>Java, Python, Cplusplus</b></p>] |
لیست
با تهیه لیستی می توانید چندین تگ را برای یافتن منتقل کنید. کد زیر همه تگ ها <b> و <pre> را پیدا می کند –
1 2 |
>>> markup.find_all(['pre', 'b']) [<pre>Programming Languages are:</pre>, <b>Java, Python, Cplusplus</b>] |
True
True تمام تگ هایی را که می تواند پیدا کند باز می گرداند، اما هیچ رشته ای به خودی خود وجود ندارد –
1 2 3 4 5 6 |
>>> markup.find_all(True) [<html><body><p>Top Three</p><p></p><pre>Programming Languages are:</pre> <p><b>Java, Python, Cplusplus</b> </p> </body></html>, <body><p>Top Three</p><p></p><pre> Programming Languages are:</pre><p><b>Java, Python, Cplusplus</b></p> </body>, <p>Top Three</p>, <p></p>, <pre>Programming Languages are:</pre>, <p><b>Java, Python, Cplusplus</b></p>, <b>Java, Python, Cplusplus</b>] |
برای برگرداندن فقط تگ های سوپ فوق –
1 2 3 4 5 6 7 8 9 |
>>> for tag in markup.find_all(True): (tag.name) 'html' 'body' 'p' 'p' 'pre' 'p' 'b' |
()find_all
برای استخراج همه وقایع یک تگ خاص از پاسخ صفحه می توانید از find_all استفاده کنید –
نحو
1 |
find_all(name, attrs, recursive, string, limit, **kwargs) |
اجازه دهید برخی از اطلاعات جالب از IMDB – “فیلم های دارای بالاترین امتیاز” در همه زمان ها را استخراج کنیم
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
>>> url="https://www.imdb.com/chart/top/?ref_=nv_mv_250" >>> content = requests.get(url) >>> soup = BeautifulSoup(content.text, 'html.parser') #Extract title Page >>> print(soup.find('title')) <title>IMDb Top 250 - IMDb</title> #Extracting main heading >>> for heading in soup.find_all('h1'): print(heading.text) Top Rated Movies #Extracting sub-heading >>> for heading in soup.find_all('h3'): print(heading.text) IMDb Charts You Have Seen IMDb Charts Top India Charts Top Rated Movies by Genre Recently Viewed |
می توانیم ببینیم find_all همه موارد مطابق با معیارهای جستجو را که تعریف می کنیم به ما می دهد. همه فیلترهایی که می توانیم با ()find_all استفاده کنیم می توانند با ()find و سایر متدهای جستجو مانند ()find_parents یا ()find_siblings نیز استفاده شوند.
()find
در بالا مشاهده کردیم، ()find_all برای اسکن کل سند برای یافتن همه مطالب استفاده می شود اما موارد دیگر، شرط یافتن تنها یک نتیجه است. اگر می دانید که سند فقط حاوی یک تگ <body> است ، جستجوی کل سند اتلاف وقت است. یک راه این است که هر بار ()find_all را با حد = 1 فراخوانی کنید در غیر این صورت می توانیم از روش ()find برای انجام همان کار استفاده کنیم –
نحو
1 |
find(name, attrs, recursive, string, **kwargs) |
بنابراین در زیر دو روش مختلف خروجی یکسانی وجود دارد –
1 2 3 4 5 |
>>> soup.find_all('title',limit=1) [<title>IMDb Top 250 - IMDb</title>] >>> >>> soup.find('title') <title>IMDb Top 250 - IMDb</title> |
در خروجی های بالا، می توانیم ببینیم که متد ()find_all لیستی شامل یک مورد را برمی گرداند در حالی که متد ()find تنها نتیجه را برمی گرداند.
تفاوت دیگر بین روش ()find و ()find_all این است:
1 2 3 4 |
>>> soup.find_all('h2') [] >>> >>> soup.find('h2') |
اگر روش ().pood.find_all چیزی پیدا نکند، لیست خالی را برمی گرداند در حالیکه ()find هیچکدام را بر نمی گرداند
()find_parents و ()find_parent
برخلاف روش های ()find_all و ()find درخت که با عبور از درخت، با نگاه به فرزندان تگ، روش ()find_parents و ()find_parents برعکس عمل می کنند، آنها درخت را به سمت بالا عبور می دهند و به والدین تگ (یا یک رشته) نگاه می کنند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
find_parents(name, attrs, string, limit, **kwargs) find_parent(name, attrs, string, **kwargs) >>> a_string = soup.find(string="The Godfather") >>> a_string 'The Godfather' >>> a_string.find_parents('a') [<a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a>] >>> a_string.find_parent('a') <a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a> >>> a_string.find_parent('tr') <tr> <td class="posterColumn"> <span data-value="2" name="rk"></span> <span data-value="9.149038526210072" name="ir"></span> <span data-value="6.93792E10" name="us"></span> <span data-value="1485540" name="nv"></span> <span data-value="-1.850961473789928" name="ur"></span> <a href="/title/tt0068646/"> <img alt="The Godfather" height="67" src="https://m.media-amazon.com/images/M/MV5BM2MyNjYxNmUtYTAwNi00MTYxLWJmNWYtYzZlODY3ZTk3OTFlXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_UY67_CR1,0,45,67_AL_.jpg" width="45"/> </a> </td> <td class="titleColumn"> 2. <a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a> <span class="secondaryInfo">(1972)</span> </td> <td class="ratingColumn imdbRating"> <strong title="9.1 based on 1,485,540 user ratings">9.1</strong> </td> <td class="ratingColumn"> <div class="seen-widget seen-widget-tt0068646 pending" data-titleid="tt0068646"> <div class="boundary"> <div class="popover"> <span class="delete"> </span><ol><li>1<li>2<li>3<li>4<li>5<li>6<li>7<li>8<li>9<li>10</li>0</li></li></li></li&td;</li></li></li></li></li></ol> </div> </div> <div class="inline"> <div class="pending"></div> <div class="unseeable">NOT YET RELEASED</div> <div class="unseen"> </div> <div class="rating"></div> <div class="seen">Seen</div> </div> </div> </td> <td class="watchlistColumn"> <div class="wlb_ribbon" data-recordmetrics="true" data-tconst="tt0068646"></div> </td> </tr> >>> >>> a_string.find_parents('td') [<td class="titleColumn"> 2. <a href="/title/tt0068646/" title="Francis Ford Coppola (dir.), Marlon Brando, Al Pacino">The Godfather</a> <span class="secondaryInfo">(1972)</span> </td>] |
هشت روش مشابه دیگر نیز وجود دارد
1 2 3 4 5 6 7 8 9 10 11 |
find_next_siblings(name, attrs, string, limit, **kwargs) find_next_sibling(name, attrs, string, **kwargs) find_previous_siblings(name, attrs, string, limit, **kwargs) find_previous_sibling(name, attrs, string, **kwargs) find_all_next(name, attrs, string, limit, **kwargs) find_next(name, attrs, string, **kwargs) find_all_previous(name, attrs, string, limit, **kwargs) find_previous(name, attrs, string, **kwargs) |
متدهای ()find_next_siblings و ()find_next_sibling تمام خواهر و برادرهای عنصری را که بعد از عنصر فعلی آمده اند تکرار می کنند.
متد های ()find_previous_siblings و ()find_previous_sibling تمام خواهر و برادرهایی را که قبل از عنصر فعلی قرار دارند تکرار خواهد کرد.
متدهای ()find_all_next و ()find_next در تمام تگ ها و رشته هایی که بعد از عنصر فعلی آمده اند تکرار می شوند.
متدهای ()find_all_previous و ()find_previous در تمام تگ ها و رشته هایی که قبل از عنصر فعلی قرار دارند تکرار می شوند.
گزینشگرهای CSS
کتابخانه BeautifulSoup برای پشتیبانی از متداول ترین انتخاب کنندگان CSS. با کمک متد ()select می توانید عناصر را با استفاده از انتخابگرهای CSS جستجو کنید.
در اینجا چند نمونه آورده شده است –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
>>> soup.select('title') [<title>IMDb Top 250 - IMDb</title>, <title>IMDb Top Rated Movies</title>] >>> >>> soup.select("p:nth-of-type(1)") [<p>The Top Rated Movie list only includes theatrical features.</p>, <p> class="imdb-footer__copyright _2-iNNCFskmr4l2OFN2DRsf">© 1990-2019 by IMDb.com, Inc.</p>] >>> len(soup.select("p:nth-of-type(1)")) 2 >>> len(soup.select("a")) 609 >>> len(soup.select("p")) 2 >>> soup.select("html head title") [<title>IMDb Top 250 - IMDb</title>, <title>IMDb Top Rated Movies</title>] >>> soup.select("head > title") [<title>IMDb Top 250 - IMDb</title>] #print HTML code of the tenth li elemnet >>> soup.select("li:nth-of-type(10)") [<li class="subnav_item_main"> <a href="/search/title?genres=film_noir&sort=user_rating,desc&title_type=feature&num_votes=25000,">Film-Noir </a> </li>] |
دیدگاه شما