می‌خواهیم یک فایل HTML را پردازش کرده و هم‌چنین اطلاعاتی را از آن استخراج کنیم. برای این کار، باید کلاسی به نام HTMLParser طراحی کنید که ویژگی‌ها و توابع زیر را دارا باشد:

class HTMLParser:
    def __init__(self, html_doc):
        self.html_doc = html_doc
        pass

    def set_html_doc(self, html_doc):
        self.html_doc = html_doc

    def find_first(self, output_arg, **finding_args):
        pass

    def find_all(self, n, output_arg, **finding_args):
        pass

    def find_parent(self, output_arg, **finding_args):
        pass

    def find_grandparent(self, n, output_arg, **finding_args):
        pass

    def remove_comment(self, **finding_args):
        pass

    def remove_all_comments(self):
        pass

    def remove_tag(self, **finding_args):
        pass

if __name__ == '__main__':
    pass

پیش از شرح توابع و ویژگی‌ها، مشخصه‌های جستجو finding_args و مشخصهٔ خروجی output_arg را شرح می‌دهیم:

مشخصه‌های جستجو (finding_args)

یک دیکشنری است که می‌تواند یک یا چند کلید از میان name ، id ، string و class بپذیرد. برای مثال برای تگی مانند مثال زیر:

<p class="important" id="some-ID">you can <i>access</i> Quera <a href="http://www.quera.ir">here</a>!</p>

مشخصهٔ name برابر p، مشخصهٔ id برابر some-ID، مشخصه‌ٔ string برابر you can access Quera here! و مشخصهٔ class برابر important می‌باشد. تضمین می‌شود مشخصه‌های جستجوی ورودی تنها شامل مشخصه‌های فوق می‌باشد.

مشخصهٔ خروجی (output_arg)

یک str است که مشخصهٔ مطلوب خروجی تابع را مشخص می‌کند و تضمین می‌شود مقادیری همانند بالا دارد. در صورتی که مقدار متناظر مشخصهٔ خروجی مقداردهی نشده بود، خروجی یک رشتهٔ خالی خواهد بود.

parser = HTMLParser("<b>some text.</b>")
>>> parser.find_first("class", name='b')
""
>>> parser.find_first("string", name='b')
"some text."
>>> parser.find_first("name", string="some text.")
'b' 

نمونه

برای مثال فراخوانی یک تابع با مشخصه‌های فوق، چنین است:

parser.find_first("string", id="link", name='a')

ویژگی‌ها و توابع این کلاس به شرح زیر هستند:

ویژگی html_doc

کل کد HTML به فرمت یک رشته str است.

متد ‍‍find_first

مقدار مشخصهٔ خروجی (output_arg) اولین برچسب که با ویژگی‌های finding_args مطابقت داشته باشد را خروجی می‌دهد.

متد ‍‍find_all

یک لیست به طول حداکثر n از مقدار مشخصه‌های خروجی برچسب‌های مطابق با finding_args را برمی‌گرداند (‍‍‍‍‍nتای اول). اگر تعداد برچسب‌های یافته‌شده کمتر از n بود لیستی به اندازهٔ همان تعداد برمی‌گرداند.

مثال:

doc = '<b id="1">first</b> <b id="2">second</b> <b>third</b>'
parser.set_html_doc(doc)
>>> parser.find_all(4, "id", name='b')
['1','2',""]

متد ‍‍find_parent

مقدار مشخصهٔ خروجی اولین والد برچسب مطابق با مشخصه‌های جستجو را خروجی می‌دهد. (در صورتی که بیش از یک برچسب یافت شد، مقدار مطلوب را برای اولین برچسب یافته‌شده خروجی می‌دهد.) تضمین می‌شود برچسب‌های یافته‌شده حداقل یک والد دارند.

مثال: ‍‍‍

parser.set_html_doc("<p><b>example</b></p>")
>>>parser.find_parent("name", name='b', string='example')
'p'

متد ‍‍find_grandparent

مقدار مشخصهٔ خروجی nاُمین جد (اولین جد همان والد است.) اولین برچسب مطابق با مشخصه‌های جستجو را خروجی می‌دهد. در صورتی که n از تعداد جدهای برچسب یافته شده بیشتر باشد، استثنایی با پیام No Such Parent پرتاب شود. تضمین می‌شود برچسب‌های یافته‌شده حداقل یک والد دارند.

متد ‍‍remove_comment

اولین برچسب منطبق با مشخصهٔ ورودی را در صورتی که فقط محتوی کامنت باشد به طور کلی از html_docحذف می‌کند. کامنت‌های ‍‍HTML به صورت زیر هستند:

<!--Some Comments-->
parser.set_html_doc('<b id="comment"><!--comment--></b>')
>>> parser.remove_comment(name='b')
>>> parser.html_doc
""
>>> parser.set_html_doc("<b>not a <!--comment--></b>")
>>> parser.remove_comment(name='b')
>>>parser.html_doc
"<b>not a <!--comment--></b>"

در صورتی که محتویات اولین برچسب یافته‌شده عاری از کامنت بود، استثایی با پیام No Comments Found پرتاب شود.

متد ‍‍remove_all_comments

تمامی برچسب‌های محتوی کامنت را از html_doc حذف می‌کند.

متد ‍‍remove_tag

اولین برچسب مطابق با مشخصات ورودی را به طور کلی از html_doc حذف می‌کند.

توجه: در تمامی متدهایی که می‌بایست برچسبی مطابق با مشخصات ورودی یافت شود، اگر برچسبی یافت نشد باید استثنایی با پیام No Such Tag پرتاب شود.

نکات

  • می‌توانید فایل اولیه این سوال را از این لینک دریافت کنید.
  • دقت کنید که در هیچ‌کدام از توابع نباید مقداری را چاپ کنید؛ تنها در توابعی که گفته شده مقداری را بازگردانید، باید مقدار مورد نظر را return کنید.

نحوه ارسال

فایل کامل شده HTMLParser.py را ارسال کنید؛ همچنین برای استفاده از کتابخانه‌های مختلف می‌توانید همراه فایل ارسالی، فایلی به نام python_requirements.txt در ZIP خود بگذارید که در آن نام کتاب‌خانه‌های مورد نیاز و شماره نسخه‌ی آن‌ها به فرمت زیر در آن موجود باشد: (اگر شماره نسخه را ننویسید آخرین نسخه‌ی آن کتابخانه نصب می‌شود)

firstlib==1.2.3
secondlib==4.5.6
...

در نهایت یک فایل ZIP حاوی دو فایل خواسته شده را آپلود کنید.

ارسال پاسخ برای این سؤال
فایلی انتخاب نشده است.