آموزش پیمایش توسط تگ ها در Beautiful Soup
آموزش پیمایش توسط تگ ها در Beautiful Soup
در این درس از مجموعه آموزش برنامه نویسی سایت سورس باران، به آموزش پیمایش توسط تگ ها در Beautiful Soup خواهیم پرداخت.
پیشنهاد ویژه : پکیج آموزش صفر تا صد پایتون
در زیر سند html ما قرار دارد –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
>>> html_doc = """ <html><head><title>Tutorials Point</title></head> <body> <p class="title"><b>The Biggest Online Tutorials Library, It's all Free</b></p> <p class="prog">Top 5 most used Programming Languages are: <a href="https://www.tutorialspoint.com/java/java_overview.htm" class="prog" id="link1">Java</a>, <a href="https://www.tutorialspoint.com/cprogramming/index.htm" class="prog" id="link2">C</a>, <a href="https://www.tutorialspoint.com/python/index.htm" class="prog" id="link3">Python</a>, <a href="https://www.tutorialspoint.com/javascript/javascript_overview.htm" class="prog" id="link4">JavaScript</a> and <a href="https://www.tutorialspoint.com/ruby/index.htm" class="prog" id="link5">C</a>; as per online survey.</p> <p class="prog">Programming Languages</p> """ >>> >>> from bs4 import BeautifulSoup >>> soup = BeautifulSoup(html_doc, 'html.parser') >>> |
بر اساس سند بالا، سعی خواهیم کرد از بخشی از سند به قسمت دیگر برویم.
پایین رفتن
یکی از عناصر مهم در هر قسمت از سندهای HTML، تگ ها هستند که ممکن است حاوی تگ ها / رشته های دیگری باشند. Beautiful Soup روش های مختلفی را برای پیمایش و تکرار تگ فرزند فراهم می کند.
پیمایش با استفاده از نام تگ ها
ساده ترین راه برای جستجوی درخت تجزیه، جستجوی تگ با نام آن است. اگر تگ <head> را می خواهید، از soup.head استفاده کنید –
1 2 3 4 |
>>> soup.head <head>&t;title>Tutorials Point</title></head> >>> soup.title <title>Tutorials Point</title> |
برای دریافت تگ خاص (مانند اولین تگ <b>) در تگ <body>.
1 2 |
>>> soup.body.b <b>The Biggest Online Tutorials Library, It's all Free</b> |
با استفاده از یک نام تگ به عنوان ویژگی تنها اولین تگ با این نام به شما داده می شود –
1 2 |
>>> soup.a <a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a> |
برای به دست آوردن تمام ویژگی های تگ، می توانید از متد ()find_all استفاده کنید –
1 2 3 |
>>> soup.find_all("a") [<a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a>, <a class="prog" href="https://www.tutorialspoint.com/cprogramming/index.htm" id="link2">C</a>, <a class="prog" href="https://www.tutorialspoint.com/python/index.htm" id="link3">Python</a>, <a class="prog" href="https://www.tutorialspoint.com/javascript/javascript_overview.htm" id="link4">JavaScript</a>, <a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm" id="link5">C</a>]>>> soup.find_all("a") [<a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a>, <a class="prog" href="https://www.tutorialspoint.com/cprogramming/index.htm" id="link2">C</a>, <a class="prog" href="https://www.tutorialspoint.com/python/index.htm" id="link3">Python</a>, <a class="prog" href="https://www.tutorialspoint.com/javascript/javascript_overview.htm" id="link4">JavaScript</a>, <a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm" id="link5">C</a>] |
.contents and .children
ما می توانیم فرزندان تگ را در لیست توسط محتوای آن جستجو کنیم –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
>>> head_tag = soup.head >>> head_tag <head><title>Tutorials Point</title></head> >>> Htag = soup.head >>> Htag <head><title>Tutorials Point</title></head> >>> >>> Htag.contents [<title>Tutorials Point</title> >>> >>> Ttag = head_tag.contents[0] >>> Ttag <title>Tutorials Point</title> >>> Ttag.contents ['Tutorials Point'] |
شی BeautifulSoup خود دارای فرزند است. در این حالت، تگ <html> فرزند شی Beautiful BeautifulSoup است –
1 2 3 4 |
>>> len(soup.contents) 2 >>> soup.contents[1].name 'html' |
این رشته محتویات ندارد، زیرا نمی تواند حاوی چیزی باشد –
1 2 3 4 |
>>> text = Ttag.contents[0] >>> text.contents self.__class__.__name__, attr)) AttributeError: 'NavigableString' object has no attribute 'contents' |
به جای استفاده از لیست به عنوان لیست، از فرزندان مولد برای دسترسی به فرزند تگ استفاده کنید –
1 2 3 |
>>> for child in Ttag.children: print(child) Tutorials Point |
.descendants
ویژگی .descendants به شما اجازه می دهد تا تمام فرزندان یک تگ را به صورت بازگشتی تکرار کنید –
فرزندان مستقیم آن و فرزندان مستقیم آن و غیره –
1 2 3 4 |
>>> for child in Htag.descendants: print(child) <title>Tutorials Point</title> Tutorials Point |
تگ <head> فقط یک فرزند دارد، اما دارای دو descendants است: تگ <title> و تگ <title>. بدنه Beautifulsoup فقط یک فرزند مستقیم دارد (برچسب <html>) ، اما تعداد زیادی از descendants دارد –
1 2 3 4 |
>>> len(list(soup.children)) 2 >>> len(list(soup.descendants)) 33 |
رشته
اگر تگ فقط یک فرزند داشته باشد و آن فرزند یک NavigableString باشد، فرزند به عنوان string. در دسترس قرار می گیرد –
1 2 |
>>> Ttag.string 'Tutorials Point' |
اگر تنها فرزند یک تگ یک تگ دیگر است، و آن تگ دارای یک رشته است. سپس برچسب والد دارای همان string. فرزند مشابه آن است –
1 2 3 4 5 |
>>> Htag.contents [<title>Tutorials Point</title>] >>> >>> Htag.string 'Tutorials Point' |
با این حال، اگر یک تگ بیش از یک چیز دارد، پس مشخص نیست که .string باید به چه چیزهایی مراجعه کند، بنابراین .string برای None تعریف می شود –
1 2 |
>>> print(soup.html.string) None |
strings and stripped_strings.
اگر بیش از یک چیز در داخل تگ وجود دارد، هنوز هم می توانید فقط رشته ها را مشاهده کنید. از ژنراتور string. استفاده کنید –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
>>> for string in soup.strings: print(repr(string)) '\n' 'Tutorials Point' '\n' '\n' "The Biggest Online Tutorials Library, It's all Free" '\n' 'Top 5 most used Programming Languages are: \n' 'Java' ',\n' 'C' ',\n' 'Python' ',\n' 'JavaScript' ' and\n' 'C' ';\n \nas per online survey.' '\n' 'Programming Languages' '\n' |
برای حذف فضای خالی اضافی، از ژنراتور .stripped_strings استفاده کنید –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
>>> for string in soup.stripped_strings: print(repr(string)) 'Tutorials Point' "The Biggest Online Tutorials Library, It's all Free" 'Top 5 most used Programming Languages are:' 'Java' ',' 'C' ',' 'Python' ',' 'JavaScript' 'and' 'C' ';\n \nas per online survey.' 'Programming Languages |
بالا رفتن
در یک قیاس “شجره نامه” ، هر تگ و هر رشته یک والد دارد
parent.
برای دسترسی به عنصر اصلی والد، از ویژگی parent. استفاده کنید.
1 2 3 4 5 |
>>> Ttag = soup.title >>> Ttag <title>Tutorials Point</title> >>> Ttag.parent <head>title>Tutorials Point</title></head> |
در html_doc ما، رشته عنوان خودش والد دارد: تگ <title> که حاوی آن است
1 2 |
>>> Ttag.string.parent <title>Tutorials Point</title> |
والد یک تگ سطح بالا مانند <html> خود شی Beautiful Beautifulsoup است –
1 2 3 |
>>> htmltag = soup.html >>> type(htmltag.parent) <class 'bs4.BeautifulSoup'> |
والد یک شی Beautifulsoup به عنوان None تعریف شده است –
1 2 |
>>> print(soup.parent) None |
parents.
برای تکرار تمام عناصر والدین، از ویژگی parents. استفاده کنید
1 2 3 4 5 6 7 8 9 10 11 12 13 |
>>> link = soup.a >>> link <a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a> >>> >>> for parent in link.parents: if parent is None: print(parent) else: print(parent.name) p body html [document] |
به کناره ها رفتن
در زیر یک سند ساده آورده شده است –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
>>> sibling_soup = BeautifulSoup("<a><b>TutorialsPoint</b><c><strong>The Biggest Online Tutorials Library, It's all Free</strong></b></a>") >>> print(sibling_soup.prettify()) <html> <body> <a> <b> TutorialsPoint </b> <c> <strong> The Biggest Online Tutorials Library, It's all Free </strong> </c> </a> </body> </html> |
در سند بالا، تگ <b> و <c> در یک سطح است و هر دو از یک تگ هستند. تگ <b> و <c> خواهر و برادر هستند.
next_sibling and .previous_sibling.
برای حرکت بین عناصر صفحه که در همان سطح درخت تجزیه هستند از next_sibling و .prebil_sibling. استفاده کنید:
1 2 3 4 5 |
>>> sibling_soup.b.next_sibling <c><strong>The Biggest Online Tutorials Library, It's all Free</strong></c> >>> >>> sibling_soup.c.previous_sibling <b>TutorialsPoint</b> |
تگ <b> دارای یک خواهر بعدی است. خواهر و برادر قبلی وجود ندارد، زیرا هیچ چیز قبل از تگ <b> در همان سطح درخت وجود ندارد، همان مورد با تگ <c> وجود دارد.
1 2 3 4 |
>>> print(sibling_soup.b.previous_sibling) None >>> print(sibling_soup.c.next_sibling) None |
این دو رشته خواهر و برادر نیستند، زیرا والدین یکسانی ندارند.
1 2 3 4 5 |
>>> sibling_soup.b.string 'TutorialsPoint' >>> >>> print(sibling_soup.b.string.next_sibling) None |
next_siblings and .previous_siblings.
برای تکرار تگ siblings از تگ خواهر و next_siblings and .previous_siblings. استفاده کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
>>> for sibling in soup.a.next_siblings: print(repr(sibling)) ',\n' <a class="prog" href="https://www.tutorialspoint.com/cprogramming/index.htm" id="link2">C</a> ',\n' >a class="prog" href="https://www.tutorialspoint.com/python/index.htm" id="link3">Python</a> ',\n' <a class="prog" href="https://www.tutorialspoint.com/javascript/javascript_overview.htm" id="link4">JavaScript</a> ' and\n' <a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm" id="link5">C</a> ';\n \nas per online survey.' >>> for sibling in soup.find(id="link3").previous_siblings: print(repr(sibling)) ',\n' <a class="prog" href="https://www.tutorialspoint.com/cprogramming/index.htm" id="link2">C</a> ',\n' <a class="prog" href="https://www.tutorialspoint.com/java/java_overview.htm" id="link1">Java</a> 'Top 5 most used Programming Languages are: \n' |
عقب و جلو رفتن
حالا اجازه دهید به دو خط اول در مثال قبلی “html_doc” خود برگردیم –
1 2 3 |
&t;html><head><title>Tutorials Point</title></head> <body> <h4 class="tagLine"><b>The Biggest Online Tutorials Library, It's all Free</b></h4> |
تجزیه کننده HTML رشته های بالاتر از کاراکترها را در اختیار شما قرار می دهد و آن را به مجموعه ای از حوادث مانند “نگ باز <html>” ، “بتگ باز<head>” ، ” تگ باز <title>” ، “اضافه کردن یک رشته” ، “بستن تگ </ title>” ، “بستن تگ </ head>” ، “باز کردن تگ <h4>” و موارد دیگر. BeautifulSoup روش های مختلفی را برای بازسازی تجزیه اولیه سند ارائه می دهد.
next_element and .previous_element.
ویژگی .next_element یک تگ یا رشته به هر آنچه بلافاصله تجزیه می شود اشاره می کند. بعضی اوقات به نظر می رسد شبیه خواهر / برادر بعدی است ، اما کاملاً یکسان نیست. در زیر تگ <a> در سند نمونه “html_doc” ما آورده شده است.
1 2 3 4 5 |
>>> last_a_tag = soup.find("a", id="link5") >>> last_a_tag <a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm" id="link5">C</a> >>> last_a_tag.next_sibling ';\n \nas per online survey.' |
با این حال، عنصر. بعدی آن تگ <a> ، چیزی که بلافاصله پس از تگ <a> تجزیه شد، و بقیه جمله نیست: این کلمه “C” است:
1 2 |
>>> last_a_tag.next_element 'C' |
رفتار بالاتر به این دلیل است که در نشانه گذاری اصلی، حرف “C” قبل از آن نقطه ویرگول ظاهر شده است. تجزیه کننده با یک تگ <a> ، سپس حرف “C” ، سپس تگ بسته شدن </a> ، سپس نقطه ویرگول و بقیه جمله مواجه شد. نقطه ویرگول در همان سطح نگ <a> است، اما ابتدا حرف “C” پیدا شد.
صفت .previous_element دقیقاً برعکس .next_element است. این به هر عنصری که بلافاصله قبل از این عنصر تجزیه شده است اشاره می کند.
1 2 3 4 5 |
>>> last_a_tag.previous_element ' and\n' >>> >>> last_a_tag.previous_element.next_element <a class="prog" href="https://www.tutorialspoint.com/ruby/index.htm" id="link5">C</a> |
next_elements and .previous_elements.
ما از این تکرارها برای حرکت به جلو و عقب به سمت یک عنصر استفاده می کنیم.
1 2 3 4 5 6 7 8 |
>>> for element in last_a_tag.next_e lements: print(repr(element)) 'C' ';\n \nas per online survey.' '\n' <p class="prog">Programming Languages</p> 'Programming Languages' '\n' |
دیدگاه شما