کامل ترین آموزش وب اسکرپینگ با پایتون

کامل ترین آموزش وب اسکرپینگ با پایتون
تاریخ بروزرسانی : 07 آذر 1401 | تعداد بازدید : 8409 | زمان خواندن مقاله : 30
پایتون،

کامل ترین آموزش وب اسکرپینگ با پایتون

اینترنت بزرگ ترین منبع داده در دنیا است. فرقی نمی کند این اطلاعات درست هستند یا نه؛ باز هم برای همه ما اصلی ترین منبع برای تحقیق و تحلیل اطلاعات و دیتایی است که در بستر وب وجود دارد. داده های موجود در اینترنت آنقدر زیاد است که می توانید در هر زمینه ای اطلاعات به دست آورده و تحقیق کنید. اما برای آنکه بتوانید این اطلاعات را جمع آوری و استخراج کنید نیاز به دانش خاصی دارید. جمع آوری داده ها از وب سایت ها را وب اسکرپینگ می گویند. عملیات وب اسکرپینگ با پایتون انجام می شود؛ چرا که پایتون قدرتمند ترین زبان برنامه نویسی موجود است.

با من همراه باشید تا هر آنچه را که باید درباره وب اسکرپینگ با پایتون بدانید؛ به شما بگویم تا مانند یک متخصص این عملیات را انجام دهید.

وب اسکرپینگ چیست؟

داده در تمامی وب سایت ها از اهمیت بالایی برخوردار است، چرا که با استفاده از داده ها می توان به داده کاوی و تجزیه و تحلیل پرداخت. اگر بخواهم خیلی خیلی ساده درباره وب اسکرپینگ با پایتون بگویم؛ جمع آوری داده های یک وب سایت را وب اسکرپینگ (Web Scraping) می گوییم. اصلی ترین و قدرتمند ترین زبان برنامه نویسی که می توان عملیات وب اسکرپینگ را با آن انجام داد؛ زبان برنامه نویسی پایتون است. وب اسکرپینگ در این زبان با استفاده از کتابخانه Beautiful Soup انجام می شود.

چالش های وب اسکرپینگ با پایتون

صفحات وب سایت ها از فناوری های بسیاری برای رشد استفاده می کند. به عبارت دیگر وب سایت یک نوع بهم ریختگی به حساب می آید. به خاطر همین هم زمانی که می خواهید عملیات وب اسکرپینگ با پایتون را انجام دهید؛ با چالش های متفاوتی رو به رو می شوید. دو مورد از مهم ترین چالش هایی که با آن رو به رو می شوید به شرح زیر است.

1.تنوع

تمامی وب سایت ها منحصر به فرد هستند و این در حالی است که همه این وب سایت ها از ساختار کلی یکسانی پیروی می کنند و این تنوع زمانی به یک چالش تبدیل می شود که بخواهید عملیات وب اسکرپینگ را انجام دهید. 
 

2.دوام

تقریبا می توان گفت هیچ وب سایتی بدون تغییر باقی نمی ماند. تمامی وب سایت ها مرتبا در حال تغییر هستند. هنگامی که می خواهید عملیات وب اسکرپینگ با پایتون را انجام دهید با یک چالش بزرگ رو به رو خواهید شد. چالش شما آنجایی است که وب اسکرپر خود را نوشته اید تا به صورت خودکار سایت را اسکرپ کند و هر آنچه را که می خواهید استخراج کند.

تا اینجای کار هنوز چالشی وجود ندارد. بار اول کد های شما بدون نقص کار خواسته شده را انجام می دهد و دیتای مورد نظر را استخراج می کند. هنوز هم چالشی وجود ندارد. شما وب اسکرپینگ با پایتون را کد نویسی کرده اید و آن ها یکبار بدون خطا نیز اجرا کرده اید. بیایید این کد ها را بعد از مدت کوتاهی؛ یکبار دیگر اجرا کنید. اینجاست که متوجه چالش می شوید.

اسکریپتی که نوشته اید تا چند روز پیش بدون نقص صفحات یک سایت را اسکرپ کرد؛ الان قادر به انجام دوباره این کار نیست. علت این ناکامی نیز تغییراتی است که در همان سایت ایجاد شده است. همانطور که متوجه شدید؛ اسکریپت های نوشته شده برای وب اسکرپینگ ناپایدار است و این یک چالش جدی در این حوزه است. وب سایت ها دائما در حال تغییر و تحول هستند. شاید کمی حس نا امیدی یا ترس به سراغتان بیاید.

اما هنوز قسمت خوب ماجرا مانده است. قسمت خوب این است که اکثر وب سایت هایی که در حال تغییر هستند، سایت های کوچک هستند و برای آنکه اسکرپر شما برای تمامی وب سایت ها جواب دهد؛ کافی است تنظیمات آن را تغییر دهید. برای آن که اسکریپت اصلی شما همیشه جواب دهد؛ باید از آن نگهداری کنید کد ها را مرتبا یکپارچه سازی کنید تا بدون نقص اجرا شوند.

 

آموزش پایتون

 

جایگزین وب اسکرپینگ با پایتون

برخی از برنامه نویسان استفاده از API ها را پیشنهاد می کنند. با استفاده از این روش می توانید با اس تفاده از روشی از پیش تعریف شده به داده های یک وب سایت دسترسی پیدا کنید. در این روش با استفاده از فرمت هایی چون JSON و XML به داده ها دست پیدا می کنید که با استفاده از API ها؛ از تجزیه HTML جلوگیری می شود.

به طور کلی؛ استفاده از این روش نسبت به وب اسکرپینگ با پایتون کمی پایدار تر است. علت این پایداری نیز این است که API ها برای مصرف برنامه نوشته می شوند اما HTML برای جذابیت های ظاهری نوشته می شود. طراحی ظاهری یک وب است ممکن است تغییر کند که این تغییر؛ تاثیری بر API سایت ندارد. به طورکلی API ها منابع قابل اعتماد تری نسبت به داده های سایت هستند؛ چرا که کمترین میزان تاثیر پذیری را دارند. با این حال دوام API ها صد در صدی نیست و آن ها نیز دستخوش تغییرات می شوند.

شروع وب اسکرپینگ با پایتون

از این لحظه به بعد دقت خود را صد برابر کنید؛ چرا که می خواهیم آموزش عملی وب اسکرپینگ با پایتون را شروع کنیم. اگر قدم به قدم با هم پیش برویم قطعا این مبحث را به طور کامل یاد می گیرید.

قبل از اینکه شروع کنیم؛ نیاز به یک وب سایت تمرینی دارید که هر آنچه را می آموزید، در لحظه پیاده سازی کنید. سایت تمرینی که قصد معرفی آن را داریم در فرآیند یادگیری وب اسکرپینگ به شما کمک فراوانی می کند. این وب سایت جعلی؛ یک سایت کاریابی است که برای تمرین وب اسکرپینگ ایجاد شده است.

ابتدا شما یک اسکرپر می سازید و از آن می خواهید تا سایت تمرینی را اسکرپ کند و به طور مثال مشاغل برنامه نویسی با پایتون را واکشی کرده و نمایش دهد. در این روش عملیات وب اسکرپینگ با پایتون انجام می شود و مطابق با این روش HTML تجزیه می شود تا اطلاعات مورد نیاز استخراج شود.

شما می توانید عملیات وب اسکرپینگ با پایتون را روی تمامی سایت هایی که در بستر وب است؛ پیاده سازی کنید. هر چقدر هم کد نویسی وب سایت پیچیده تر باشد، وب اسکرپینگ نیز پیچیده تر می شود، اما ساختار کلی فرآیند وب اسکرپینگ با پایتون هیچ تغییری نمی کند.

 

داده کاوی در پایتون

بیشتر بخوانید:

داده کاوی با پایتون، برای سفر به اعماق داده آماده ای؟

 

گام اول
قبل از شروع؛ سایت مد نظر را بررسی کنید.

برای شروع وب اسکرپینگ با پایتون باید سایتی را که می خواهید عملیات اسکرپ را روی آن انجام دهید؛ به طور کامل بررسی کنید. برای آن که بتوانید عملیات اسکرپ کردن را به درستی انجام دهید، باید ساختار آن سایت را به درستی درک کرده باشید. ابتدا سایتی را که می خواهید اسکرپ کنید؛ باز می کنید. در اینجا می توانید از سایت تمرینی که معرفی کردیم استفاده کنید. با وب سایت مانند یک کاربر معمولی رفتار کنید. شروع به جستجو کنید، کلیک کنید، اسکرول کنید، به طور کلی با وب سایت تعامل داشته باشید.

در ویدیو پایین؛ محیط سایت را به شما نشان دادم و کمی با آن تعامل داشتم تا با این سایت تمرینی بیشتر آشنا شوید. نکته بسیار مهمی هم که باید اینجا بگویم این است که حتما حتما سایت تمرینی را باز کنید و مرحله به مرحله با من پیش بیایید تا متوجه تک تک نکاتی که می گویم بشوید. یکم قبل تر لینک را هم در متن قرار داده ام تا دسترسی آسان تری داشته باشید.

بررسی سایت تمرینی برای وب اسکرپینگ با پایتون 

همانطور که در ویدیو نیز مشاهده می کنید؛ آگهی های کاریابی دارای دو دکمه هستند که یکی از آن ها Apply است. مانند کاری که من اینجا انجام دادم؛ شما نیز اگر روی دکمه اپلای کلیک کنید؛ به صفحه دیگری می روید که اطلاعات بیشتری درباره آن موقعیت شغلی ساختگی به شما می دهد.

اما نکته ای که اینجا می خواهم بگویم خیلی خیلی مهم است. یکبار دیگر به عقب برگردید.

این بار به URL این دو صفحه نگاه کنید. متوجه تغییر URL ها شدید؟ یکبار دیگر به صفحه اصلی برگردید. نشانگر موس خود را تکان دهید و با سایت تعامل برقرر کنید. متوجه می شوید که هر کدام از آگهی ها URL اختصاصی خود را دارد.

URL ها را رمزگشایی کنید

در این بخش از عملیات وب اسکرپینگ با پایتون؛ تمام تمرکز ما روی URL ها و رمزگشایی از اطلاعاتی است که در آن ها پنهان شده است. اگر بتوانید URL ها را رمز گشایی کنید؛ قطعا فرآیند وب اسکرپینگ را آسان کرده اید، چرا که برنامه نویسان اطلاعات بسیار زیادی را در آدرس URL جای می دهند. از آنجایی که «شنیدن؛ کی بود مانند دیدن» یک URL از سایت تمرینی بر می داریم و اینجا به تشریح و رمز گشایی از آن می پردازیم.

https://realpython.github.io/fake-jobs/jobs/senior-python-developer-0.html

URL بالا از 2 بخش اصلی تشکیل شده است. بخش اول که در باکس زیر آمده است؛ URL پایه است که مسیر جستجوی شما را نشان می دهد.

https://realpython.github.io/fake-jobs

اما مقصد نهایی شما و مکان خاصی که رفته اید؛ در بخش دوم URL قابل مشاهده است. 

/jobs/senior-python-developer-0.html

چند آگهی را بررسی کنید. اگر دقت کنید؛ خواهید دید که تمامی آگهی ها از یک URL پایه استفاده کرده اند و در مقابل آن تمامی آگهی ها در بخش دوم؛ URL اختصاصی خود را دارند. همانطور که مشاهده کردید؛ با استفاده از URL ها می توان اطلاعات بسیاری را در مورد مکان فایل ها به دست آورد.

بعضی از سایت ها از پارامتر های جستجو برای رمزگذاری مقادیری که هنگام جستجو ارسال می کنید؛ استفاده می کنند. این پارامتر ها به عنوان رشته های پرس و جو در نظر گرفته می شوند که برای بازیابی رکورد های خاص به پایگاه داده ارسال شده اند.

پارامتر های جستجو را می توان در انتهای URL پیدا کرد. به عنوان مثال می توان به یک سایت واقعی مانند Indeed مراجعه کنید. از طریق نوار جستجو عبارات «Backend developer» در «Canada» را سرچ کنید. آنچه مشاهده می کنید؛ این است که URL تغییر می کند و این مقادیر را به عنوان مقادیر جستجو در نظر می گیرد. بدون مثال اصلا ممکن نیست. پس بریم سراغ یک مثال تا بهتر متوجه موضوع شویم. 

https://au.indeed.com/jobs?q=Backend+developer&l=Canada


پارامتر های جستجو در این URL عبارت است از:

?q=Backend+developer&l=Canada 

همانطور که مشاهده می کنید این پارامتر از سه بخش تشکیل شده است. بخش اول ابتدای پارامتر جستجو است که با علامت سوال مشخص شده است. همانطور که مشاهده می کنید؛ بخش دوم شامل اطلاعاتی است که این پارامتر به ما می دهد. قطعاتی که یک پارامتر جستجو را تشکیل می دهند به صورت جفت (کلید-مقدار)؛ کد گذاری می شوند.

منظور دقیقا آنجایی است که با استفاده از علامت (=) به یکدیگر مرتبط شده است. بخش سوم نیز جدا کننده است که در این بخش هر URL می تواند چند پارامتر جستجو داشته باشد. که با علامت (&l) از هم جداشده اند.

برای تمرین در این بخش می توانی پارامتر های جستجو را تغییر دهید و ببینید که چگونه URL را تغییر می دهند. همانطور که دیدید؛ تجزیه و تحلیل و رمزگشایی یک URL اطلاعات بسیاری در مورد نحوه بازیابی دیتا ها به شما می دهد.

ساختار سایت را با ابزار های توسعه بررسی کنید

در این مرحله از وب اسکرپینگ با پایتون؛ باید درباره نحوه ساختار داده ها اطلاعات بیشتری به دست آورید. در اینجا شما نیاز به اطلاعاتی دارید که این اطلاعات از تحلیل ساختار صفحه به دست می آید. ابزار های توسعه دهنده به شما این امکان را می دهند که ساختار یک وب سایت را به راحتی درک کنید. تمامی مروگر های اینترنت دارای ابزار های توسعه هستند.

یکی از مرورگر هایی که ما ایرانی ها بیشترین استفاده را از آن می کنیم؛ مرورگر Chrome هست. پس تحلیل و بررسی را نیز با استفاده از این مرورگر انجام می دهیم.

در سیستم عامل های ویندوز و لینوکس؛ برای دسترسی به ابزار توسعه می توانید مطابق ویدیو؛ مراحل زیر را طی کنید. 


اگر ویدیو به هر دلیلی باز نشد؛ نگران نشوید. مراحلی که در ویدیو گفته ایم به ترتیب زیر است:

  • مرورگر کروم خود را باز کنید
  • در گوشه بالایی در سمت راست؛ روی (⋮) کلیک کنید
  • به قسمت More tools بروید
  • به قسمت Devrloper tools بروید


همانطور که در منو مشاهده می کنید؛ می توانید از کلید های میانبر ctrl+shift+I نیز می توانید استفاده کنید تا مستقیما به قسمت ابزار های توسعه بروید. 
راه سومی که برای باز کردن ابزار توسعه مروگر وجود دارد؛ این است که بر روی صفحه سایت کلیک راست کنید، گزینه Inspect را انتخاب کنید و با دو کلیک به ابزار ها دسترسی پیدا کنید.

از آنجایی که همه کاربران از ویندوز یا لینوکس استفاده نمی کنند و افرادی نیز وجود دارند که از سیستم عامل mac os استفاده کنند؛ پس مراحل دسترسی به ابزار های توسعه در این سیستم عامل را  نیز می گویم. مراحل دسترسی به ابزار های توسعه در سیستم عامل macOS به ترتیبی است که در باکس زیر گفته ایم.

View → Developer → Developer Tools

همچنین با استفاده از کلید های میانبر Cmd+Alt+I می توانید مستقیما به ابزار های توسعه دست پیدا کنید. 
با استفاده از این ابزار ها می توانید به طور تعاملی DOM را در صفحات وب خود کاوش کنید. اگر در ابزار های توسعه؛ تب Elements را باز کنید، ساختاری با عناصر HTML قابل کلیک؛ باز خواهد شد. در این مرحله می توانید عناصر را مستقیما از مرورگر خود جمع آوری کنید و حتی همین‌جا به گسترش بپردازید. همانطور که در تصویر زیر مشاهده می کنید؛ کد های HTML درسمت راست قرار دارد، و با هر کلیک روی هر خط کد متوجه می شوید این کد مربوط به کدام قسمت است.

حتما حتما در این صفحه تعامل کنید و تمام قسمت های آن را کاوش کنید تا با تمامی بخش های صفحات سایت آشنا شوید و عملیات وب اسکرپینگ با پایتون را آسان تر انجام دهید. البته خیلی خود را غرق در کد های HTML نکنید. عملیات وب اسکرپینگ با قدرتمند ترین زبان برنامه نویسی؛ یعنی پایتون انجام می شود.

گام دوم

کد های HTML یک صفحه را اسکرپ کنید

در این مرحله از عملیات وب اسکرپینگ با پایتون؛ بالاخره نوبت به استفاده از پایتون رسیده است. برای شروع باید کد های HTML سایت مدنظرتان را در اسکریپت پایتون وارد کنید. برای آن که با این کد ها تعامل داشته باشید؛ از کتابخانه های پایتون درخواست های متفاوت کنید.

یک محیط مجازی virtual) environment) جدید برای پروژه خود تعریف کنید. محیط مجازی خود را فعال کنید و دستور زیر را در ترمینال وارد کنید تا کتابخانه requests نصب شود.

$ python -m pip install requests

حالا نوبت آن است که یک فایل جدید در کد ادیتور خود باز کنید. 

از قطعه دستور زیر استفاده کنید تا کد های HTML بازیابی شود. 

import requests

URL = "https://realpython.github.io/fake-jobs/"
page = requests.get(URL)

print(page.text)

با استفاده از این قطعه کد درخواست HTTP GET را به URL  سایت تمرینی ارسال می کنید. این کد داده های HTML را بازیابی می کند و آن ها را در یک شی پایتون ذخیره می کند. اگر اتربیوت (.text) را وارد کنید؛ متوجه می شوید که دقیقا مشابه کد های HTML ای است که با استفاده از Developer tools بررسی کردیم.

دوست من تا اینجای کار ما درست بوده و عملکرد خوبی داشتیم و توانستیم محتوای یک سایت استاتیک را با موفقیت از اینترنت بگیریم. اکنون از اسکریپت پایتون خود به کد های HTML سایت تمرینی دسترسی دارید. کد های HTML یکی از آگهی ها سایت تمرینی را در ادامه آورده ام تا کمی آن را درک کنیم.

<div class="card">
  <div class="card-content">
    <div class="media">
      <div class="media-left">
        <figure class="image is-48x48">
          <img
            loading="lazy" src="https://files.realpython.com/media/real-python-logo-thumbnail.7f0db70c2ed2.jpg"
            alt="Real Python Logo"
          />
        </figure>
      </div>
      <div class="media-content">
        <h2 class="title is-5">Senior Python Developer</h2>
        <h3 class="subtitle is-6 company">Payne, Roberts and Davis</h3>
      </div>
    </div>

    <div class="content">
      <p class="location">Stewartbury, AA</p>
<p class="is-small has-text-grey">
        <time datetime="2021-04-08">2021-04-08</time>
      </p>
    </div>
    <footer class="card-footer">
      <a
        href="https://www.realpython.com"
        target="_blank"
        class="card-footer-item"
        >Learn</a
      >
      <a
        href="https://realpython.github.io/fake-jobs/jobs/senior-python-developer-0.html"
        target="_blank"
        class="card-footer-item"
        >Apply</a
      >
    </footer>
  </div>
</div>

اگر یادتان باشد هنگامی که کد های HTML سایت تمرینی را با ابزار توسعه باز کردیم؛ کلی کد طولانی و نامرتب مانند قطعه کد بالا دیدیم. این گونه نامرتبی در کد ها می تواند دردسر ساز شود.

برای آن که کد ها خوانا تر شود و درک آن ها آسان تر شود؛ بهتر است از یک HTML formatter استفاده کنید. این ابزار کد ها را به صورت خودکار پاکسازی می کند و خوانایی آن را بالا می برد. برای یکبار هم که شده این ابزار را امتحان کنید و نتیجه آن را ببینید. یادتان نرود که هر سایتی ساختار مختص به خودش را دارد و به همین علت باید کد های آن را با دقت تمام بررسی و درک کنید تا بتوانید عملیات وب اسکرپینگ با پایتون را به درستی انجام دهید.

برگردیم به آگهی استخدام در سایت تمرینی و کد های آن را دقیق تر بررسی کنیم. اگر حس کردید میان انبوه کد ها سردرگم شده اید؛ کافی است به سراغ ابزار های توسعه مرورگر خود بروید و با تعاملی که بین کد ها و صفحه سایت وجود دارد؛ به کاوش بخش های مختلف صفحات بپردازید.

job_elements = results.find_all("div", class_="card-content")

همانطور که در کد های بالا مشاهده می کنید کد های HTML  دارای کلاس بندی است، که این کلاس بندی ها به شرح زیر می باشد:

  • class="title is-5": کلاسی که عنوان آگهی را نشان می دهد.
  • class="subtitle is-6 company": کلاسی که نام کمپانی ارائه دهنده آگهی را نشان می دهد.
  • class="location": کلاسی که موقعیت مکانی محل کار را نشان می دهد. 

کتابخانه ریکوئست در فرآیند وب اسکرپینگ با پایتون بسیار قدرتمندانه عمل کرده است و قطعا شما نیز متوجه این موضوع شده اید. این کتابخانه قدرتمند با رابط کاربری جذابی که دارد؛ تنها با چند خط کد به شما این امکان را داد تا کد های HTML این سایت ایستا را استخراج کنید و آن را مورد مطالعه و گسترش قرار دهید.

 

تنسورفلو در پایتون

بیشتر بخوانید:

0 تا 100 تنسورفلو در پایتون، برای سفر به اعماق داده آماده ای؟

 

 

چالش های مهم در فرآیند وب اسکرپینگ با پایتون

در طی فرآیند وب اسکرپینگ با پایتون قطعا چالش های متفاوتی وجود دارد. در اینجا مهم ترین چالش هایی که ممکن است در حین انجام وب اسکرپینگ با پایتون تجربه کنید را به شما می گویم.

وب سایت های مخفی

برخی از صفحات در وب سایت های مختلف وجود دارند که برای دسترسی به اطلاعات آن ها باید در آن سایت ها عضو شوید. در این گونه وب سایت ها فرآیند درخواست HTTP از اسکریپت پایتون با دسترسی از طریق مرورگر؛ تفاوت دارد. فقط به این دلیل که می توانید با مرورگر خود وارد صفحه شوید، به این معنی نیست که می توانید عملیات وب اسکرپینگ با پایتون را با استفاده از اسکریپت پایتون خود انجام دهید.

البته باید بگویم که کتابخانه ریکوئست را دست کم نگیرید؛ چرا که این کتابخانه خفن و قدرتمند دارای ظرفیت داخلی است و با استفاده از آن می تواند عملیات احراز هویت را انجام دهد. در حین برخورد با این گونه وب سایت ها باید هنگام درخواست  HTTP از اسکریپت پایتون خود وارد وب ‌سایت‌ شوید و اطلاعاتی را که تنها با عضویت در سایت می توان به دست آورد را اسکرپ کنید.

وب سایت های پویا

در فرآیند وب اسکرپینگ با پایتون، اسکرپ کردن وب سایت های استاتیک آسان تر از وب سایت های پویا است. علت این اتفاق نیز این است که سرور یک صفحه HTML را برای شما ارسال می کند. این صفحه تمامی اطلاعاتی را که نیاز دارید؛ شامل شده است. در وب سایت های ایستا می توانید کد های HTML را بلافاصله پس از استخراج؛ اسکرپ کنید و داده های مورد نیازتان را به دست آورید.

اگر بخواهید عملیات وب اسکرپینگ با پایتون را برای سایت های پویا انجام دهید؛ این احتمال وجود دارد که سرور کد های HTML را ارسال نکند. البته به جای آن کد های جاوا اسکریپت را برای شما ارسال می کند. اگر کد های ارسالی سرور را با کد هایی که توسط مرورگر و ابزار توسعه دیده اید؛ مقایسه کنید متوجه این تفاوت ها می شوید. 

گام سوم

ورود Beautiful Soup به عملیات وب اسکرپینگ با پایتون

در این مرحله از وب اسکرپینگ با پایتون؛ با استفاده از کتابخانه Beautiful Soup کد های HTML را تجزیه می کنیم. تا اینجای کار توانستیم کد های HTML را اسکرپ کنید اما اگر به این کد ها نگاه کنیم متوجه می شویم که خیلی مرتب نیست. هزاران اتربیوت در بین این کد ها وجود دارد؛ حتی ممکن است کد های جاوا اسکریپت نیز با این کد ها ترکیب شده باشند. وقت آن رسیده که عملیات وب اسکرپینگ با پایتون وارد مرحله جدیدی شود. در این مرحله جدید کد ها را با کتابخانه پایتون تجزیه می کنیم تا داده های مورد نظرمان استخراج شود.

Beautiful Soup یکی از کتابخانه های مهم پایتون است که فرآیند تجزیه داده های ساخت یافته را بر عهده دارد. اگر مراحل وب اسکرپینگ با پایتون را از ابتدا طی کرده باشید؛ متوجه عملکرد این کتابخانه می شوید؛ چرا که تعامل Beautiful Soup با کد های HTML مشابه با تعامل با یک صفحه وب در مرورگر با استفاده از ابزار های توسعه است. تجزیه داده ها در این کتابخانه با استفاده از چند تابع بصری صورت می گیرد. برای شروع از ترمینال استفاده می کنیم و Beautiful Soup رانصب می کنیم.

$ python -m pip install beautifulsoup4

سپس، کتابخانه را در اسکریپت پایتون خود وارد کنید و یک شی Beautiful Soup ایجاد کنید:

import requests
from bs4 import BeautifulSoup

URL = "https://realpython.github.io/fake-jobs/"
page = requests.get(URL)

soup = BeautifulSoup(page.content, "html.parser")

بهتر است قبل از هر کاری این چند خط کد را تحلیل و بررسی کنیم که متوجه شویم هر کدام از این دستور ها برای چه کاری است.
شاید برای شما این سوال پیش آمده است که چرا این دو خط کد رنگی متفاوت دارد. هنگامی که این دو خط کد را به کد های خود اضافه می کنید؛ یک شی Beautiful Soup ایجاد می شود. این شی page.content را که همان کد های HTML است که قبلا اسکرپ کرده اید؛ به عنوان ورودی می گیرد. 

نکته ای که اینجا باید اضافه کنم این است که برای جلوگیری از مشکلاتی که بر اثر رمز گذاری کاراکتر ها به وجود می آید به جای استفاده از page.text از page.content استفاده کردیم. page.content بایت های خام را در خود نگهداری می کند که این مورد بهتر از نمایش کدی است که با ویژگی های یک متن نوشته شده است و قرار است رمز گشایی شود. html.parser نیز برای آن آورده ایم که اطمینان حاصل کنیم که تجزیه کننده مناسبی را برای محتوای HTML خود انتخاب کرده ایم.

پیدا کردن عناصر با ID

همانطور که می دانید در یک صفحه وب HTML هر عنصر می تواند یک ID مختص به خود داشته باشد. این ID ها برای المنت های پایتون حکم اثر انگشت دارند و آن ها را منحصر به فرد می کند. کاربرد ID در عملیات وب اسکرپینگ با پایتون این است که می توانید تجزیه صفحه وب خود را با انتخاب یک عنصر خاص و شناسه آن شروع کنید. در اینجا نیز دقیقا همین کار را انجام می دهیم.

به سراغ ابزار های توسعه در صفحه مرورگر می رویم و شی را که حاوی تمامی آگهی های شغلی است؛ شناسایی می کنیم. عمل بررسی و تجزیه را با نگه داشتن ماوس روی قسمت هایی از صفحه و کلیک راست انجام دهید. این کار باعث می شود تا مرتبا به مرورگر خود سر بزنید و مرتبا با صفحه وب خود تعامل داشته باشید و عناصری راکخ نیازدارید فورا بیابید.

به سراغ کد ها می رویم. عنصری که به دنبال آن می گردیم؛ یک <div> است که حاوی مقدار "ResultsContainer" باشد

<div id="ResultsContainer">
  <!-- all the job listings -->
</div>

کتابخانه Beautiful Soup به شما این امکان را می دهد که عنصر HTML موردنظرتان را به همراه ID پیدا کنید.

results = soup.find(id="ResultsContainer")

برای آن که کد ها را راحت تر شناسایی کنیم؛ می توانیم هر شی Beautiful Soup را هنگام چاپ زیبا تر کنیم. اگر از ()prettify. را  روی کد بالا فراخوانی کنیم؛ آنگاه تمامی <div> ها را نمایش می دهد. از آنجایی که از شناسه عنصر استفاده کردیم، توانستیم آن را از سایر عناصر جدا کنیم. اکنون فقط یک قسمت کوچک از کد های  HTML را در دسترس داریم و می توانیم با این بخش کار کنیم.

print(results.prettify())

پیدا کردن عناصر بر اساس نام کلاس

به سایت تمرینی بروید. اگر کمی دقت کنید؛ متوجه می شوید که هر آگهی شغلی در یک عنصر div با محتوای کارت کلاس جای گرفته است. با این روش می توانید شی خود را با استفاده از نام کلاس فراخوانی کنید. 

همانطور که در کد بالا مشاهده می کنید، با استفاده از ()find_all.  یک شی را در کتابخانه Beautiful Soup فراخوانی کرده ایم. این فراخوانی برای نمایش تمامی موقعیت های شغلی در آن صفحه است.
حال می توان همه موقعیت های شغلی را مشاهده کرد.

for job_element in job_elements:
    print(job_element, end="\n"*2)

همانطور که قبلا مشاهده کردید؛ صفحه وب شما دارای نام کلاس های توصیفی در بعضی المنت ها است. با استفاده از دستور ()find. می توانیدعناصر فرزند را از تمامی موقعیت های شغلی استخراج کنید.

for job_element in job_elements:
    title_element = job_element.find("h2", class_="title")
    company_element = job_element.find("h3", class_="company")
    location_element = job_element.find("p", class_="location")
    print(title_element)
    print(company_element)
    print(location_element)
    print()

هر job_element یک شی ()Beautiful Soup است. در این مرحله از وب اسکرپینگ با پایتون می توانید دقیقا همان کار هایی را که برای المنت های والد انجام دادید؛ برای فرزند نیز انجام دهید. 

قدم به قدم به دیتایی که می خواهیم نزدیک تر می شویم.

استخراج متن از عناصر HTML

در این مرحله از وب اسکرپینگ با پایتون هدف ما استخراج داده های «عنوان موقعیت شغلی»، « شرکت» و «موقعیت مکانی موقعیت شغلی» است و این کار را با استفاده از Beautiful Soup  به بهترین شکل ممکن انجام دادیم. کافی است text content را به کتابخانه اضافه کنید تا محتوای متنی را که شامل عناصر خواسته شده است؛ برگرداند.

for job_element in job_elements:
    title_element = job_element.find("h2", class_="title")
    company_element = job_element.find("h3", class_="company")
    location_element = job_element.find("p", class_="location")
    print(title_element.text)
    print(company_element.text)
    print(location_element.text)
    print()

با اجرای این قطعه کد؛ متن تمامی المنت ها را خواهید دید. با این حال ممکن است مقدار زیادی فضای خالی هم دریافت کنید. از آنجایی که عملیات وب اسکرپینگ را با پایتون انجام می دهیم، می توانیم از فضای خالی را با استفاده از متد ()strip. تمامی فضا های اضافی که همان space ها هستند را حذف کنیم. در ادامه کد های این قسمت را نیز آورده ام. (نظر شخصی من: هر بار که درباره پایتون صحبت می کنم؛ شگفت زده می شوم و یک بار دیگر عاشق این زبان همه فن حریف می شوم.)

for job_element in job_elements:
    title_element = job_element.find("h2", class_="title")
    company_element = job_element.find("h3", class_="company")
    location_element = job_element.find("p", class_="location")
    print(title_element.text.strip())
    print(company_element.text.strip())
    print(location_element.text.strip())
    print()

خروجی این کد بهتر از آن چیزی است که فکر می کنید.

Senior Python Developer
Payne, Roberts and Davis
Stewartbury, AA

Energy engineer
Vasquez-Davidson
Christopherville, AA
Legal executive
Jackson, Chambers and Levy
Port Ericaburgh, AA

خروجی که تماشا می کنید، یک لیست قابل خواندن از اطلاعاتی است که از آگهی ها استخراج کرده ایم. این لیست شامل موقعیت شغلی، نام شرکت کارفرما و موقعیت مکانی این موقعیت های شغلی است. اگر دقت کنید این خروجی تمامی موقعیت های شغلی را نمایش داده است و این درحالی است که ما به دنبال یک موقعیت شغلی خاص هستیم. اینجا است که فرآیند وب اسکرپینگ با پایتون وارد مرحله جدیدی می شود.

پیدا کردن عناصر با نام کلاس و محتوای متنی

در این مرحله از وب اسکرپینگ با پایتون؛ روش پیدا کردن دیتای مورد نظرمان را هوشمندانه تر می کنیم. در این روش از کلاس و محتوای متن استفاده می کنیم تا وب اسکرپینگ با پایتون خروجی دقیق تری به ما بدهد. علت استفاده از محتوای متن یا همان text content این است که تمامی آگهی های شغلی نمایش داده نشود و تنها آن موقعیت های که با استفاده از کلمه کلیدی درخواست کرده ایم؛ نمایش داده شود.

عملیات وب اسکرپینگ با پایتون؛ یکی از هوشمندانه ترین انتخاب هایی است که یک وب اسکرپر حرفه ای می تواند داشته باشد. یکبار دیگر به سراغ ابزار های توسعه در مرور گر می رویم. بررسی می کنیم که عناوین شغلی با چه تگی نشان داده می شود. پس از آنکه بررسی کردید؛ قطعا متوجه می شوید که این کار با استفاده از تگ <h2> نشان داده می شود. در فرآیند وب اسکرپینگ با پایتون؛ برای آن که المنت های خاصی را نمایش دهیم از رشته ها استفاده می کنیم.

python_jobs = results.find_all("h2", string="Python")

کاربرد این دستور در وب اسکرپینگ با پایتون؛ در این است که این کد همه عناصر h2 ای را پیدا می کند که دارای کلمه پایتون در محتوای آگهی باشند. توجه کنید که در این مرحله از وب اسکرپینگ با پایتون؛ درخواست کرده ایم که تمامی نتایجی را که شامل h2 یا همان موقعیت های شغلی که پیرامون پایتون هست، نمایش دهد. حالا خروجی این کد را در کنسول تماشا کنید.

تعجب کردید که کنسول خالی است؟ حتما با خودتان می گویید یک موقعیت شغلی پایتون وجود داشت؛ پس چرا چیزی نمایش داده نمی شود؟

>>> print(python_jobs)
[]

اگر به کدی که نوشته اید نگاه کنید؛ متوجه می شوی که برای پیدا کردن داده مورد نظر از =srting استفاده کرده ایم. این دستور در وب اسکرپینگ با پایتون دقیقا آن رشته ای را جستجو می کند که نوشته اید و اگر آگهی اصلی از نظر املایی، بزرگ و کوچکی حروف، فضای خالی و موارد دیگر؛ با متن شما تفاوت داشته باشد؛ در نتایج نشان داده نمی شود. قطعا راهی برای رفع این مشکل در فرآیند وب اسکرپینگ با پایتون وجود دارد که در ادامه به آن می پردازیم.

استفاده از Beautiful Soup در وب اسکرپینگ با پایتون

وب اسکرپینگ با پایتون به لحظات پایانی خود نزدیک می شود. در ین مرحله شاهد استفاده از کتابخانه Beautiful Soup در فرآیند وب اسکرپینگ هستیم. با استفاده از این کتابخانه می توانید علاوه بر رشته ها؛ توابع را نیز به عنوان آرگومان به متد ها اضافه کنید. بهتر است کد نوشته شده را اصلاح کنیم و به جای رشته از تابع استفاده کنیم.

python_jobs = results.find_all(
    "h2", string=lambda text: "python" in text.lower()
)

اکنون یک تابع ناشناس را به عنوان آرگومان به استرینگ داده ایم. تابع لامبدا به متن هر عنصر تگ h2  نگاه می کند، تمامی حروف بزرگ را به کوچک تبدیل می کند و بررسی می کند که آیا کلمه کلیدی python در جایی یافت می شود یا خیر. یکبار دیگر به سراغ کنسول می رویم که ببینیم آیا وب اسکرپینگ با پایتون را به درستی انجام داده ایم.

>>> print(len(python_jobs))
10

بله؛ موفق شدیم. بالاخره توانستیم اطلاعات دقیق تری به دست بیاوریم. همانطور که مشاهده می کنیم با استفاده از کتابخانه Beautiful Soup در عملیات وب اسکرپینگ با پایتون؛ توانستیم 10 موقعیت شغلی را که در آن ها کلمه کلیدی "python" وجود دارد؛ استخراج کنیم. قطعا شما نیز مثل من از خروجی عملیات وب اسکرپینگ با پایتون شگفت زده شده اید.

پیدا کردن داده هایی که مد نظر دارید با استفاده از عنصر متن و کلمه کلیدی می تواند یک راه آسان اما قدرتمند در فرآیند وب اسکرپینگ با پایتون باشد. کتابخانه Beautiful Soup نیز به شما این امکان را می دهد که از رشته ها یا توابع به عنوان آرگومان استفاده کنید و جستجوی دقیق و هوشمندانه ای داشته باشید. البته ممکن است در این مسیر با خطا هایی مانند خطای زیر نیز رو به رو شوید. 

AttributeError: 'NoneType' object has no attribute 'text'


این خطا؛ یک خطای متداول است  که در حین عملیات وب اسکرپینگ با پایتون دیده می شود. به  نظر شما این خطا از کجا آمده است؟

خطایابی در وب اسکرپینگ با پایتون

وقتی به المنت های python_jobs نگاه می کنید؛ تنها چیزی که می بینید موقعیت های شغلی است که فقط از عنصر h2 تشکیل شده است و فقط عناوین شغلی را نمایش می دهد.

<h2 class="title is-5">Senior Python Developer</h2>

البته این خروجی؛ دقیقا همان چیزی است که درخواست کرده اید. به کدی که نوشتید برگردید و آن را بازبینی کنید. شما درخواست کرده اید تگ h2 بررسی شود و فقط موقعیت های شغلی که دارای کلمه کلیدی پایتون هستند، نمایش داده شود. پیام اروری که در آن بخش از وب اسکرپینگ با پایتون دریافت کرده اید را مرور کنید. اشکالی ندارد اگر حضور ذهن ندارید؛ آن را در باکس پایین نشان می دهم.

AttributeError: 'NoneType' object has no attribute 'text'

ما سعی کردیم عنوان شغل، نام شرکت و مکان شغل را در هر عنصر در python_jobs پیدا کنیم، اما هر عنصر فقط حاوی متنی با عنوان شغل است.کتابخانه diligent parsing همچنان به دنبال دیتا هایی که درخواست داده اید؛ می گردد اما چیزی پیدا نمی کند و none را بر می گرداند. اطلاعاتی که به دنبال آن هستیم را باید در تگ های تو در تو پیدا کنیم و برای این کار باید از کتابخانه Beautiful Soup استفاده کنیم.

دسترسی به عناصر والد

یکی از راه هایی که می توانید به اطلاعات مورد نیازتان دسترسی پیدا کنید؛ دسترسی به عناصر والد است. برای دسترسی به عناصر والد باید از سلسله مراتب DOM استفاده کنید. با استفاده از DOM شروع به شناسایی عناصر h2 می کنید. لازم است یکبار دیگر به صفحه مرور گر خود بروید و تگ h2 را که شامل عنوان شغلی است و همچنین نزدیک ترین تگ را که شامل اطلاعات مد نظرتان است را پیدا کنید.

<div class="card">
  <div class="card-content">
    <div class="media">
      <div class="media-left">
        <figure class="image is-48x48">
          <img
            loading="lazy" src="https://files.realpython.com/media/real-python-logo-thumbnail.7f0db70c2ed2.jpg"
            alt="Real Python Logo"
          />
        </figure>
</div>
      <div class="media-content">
        <h2 class="title is-5">Senior Python Developer</h2>
        <h3 class="subtitle is-6 company">Payne, Roberts and Davis</h3>
      </div>
    </div>

    <div class="content">
      <p class="location">Stewartbury, AA</p>
      <p class="is-small has-text-grey">
        <time datetime="2021-04-08">2021-04-08</time>
      </p>
    </div>
    <footer class="card-footer">
      <a
        href="https://www.realpython.com"
        target="_blank"
        class="card-footer-item"
        >Learn</a
      >
      <a
        href="https://realpython.github.io/fake-jobs/jobs/senior-python-developer-0.html"
        target="_blank"
        class="card-footer-item"
        >Apply</a
      >
    </footer>
  </div>
</div>

عنصر <div> با کلاس card-content حاوی تمام اطلاعاتی است که می خواهیم استخراج کنیم. این یک والد سطح سوم تگ  <h2> است که با استفاده از فیلتر پیدا کردیم. اکنون می توانیم اطلاعاتی که می خواهیم را با استفاده از عناصر والد پیدا کنیم که این کار را با استفاده از python_jobs انجام می دهیم.

python_jobs = results.find_all(
    "h2", string=lambda text: "python" in text.lower()
)

python_job_elements = [
    h2_element.parent.parent.parent for h2_element in python_jobs
]

در این مرحله از وب اسکرپینگ با پایتون؛ یک لیست را اضافه می کنیم. این لیست روی هر کدام از عناصر h2 در python_jobs با عبارت lambda یک فیلتر ایجاد می کنیم. پس از انجام این مرحله سه نسل از عناصر را خواهیم دید. وقتی به کد های HTML یک موقعیت شغلی در سایت تمرینی نگاه می‌کنیم، متوجه می شویم که این عنصر والد خاص با نام کلاس card-conten، تمام اطلاعات مورد نیاز ما را نشان می دهد.

برای مرحله بعد وب اسکرپینگ با پایتون؛ باید کد موجود در حلقه for را برای تکرار روی عناصر والد تطبیق دهیم:

for job_element in python_job_elements:
    # -- snip --

وقتی این بار کد های وب اسکرپینگ باپایتون را اجرا می کنیم؛ خواهیم دید که کد های ما تمام اطلاعات مد نظرما را بر می گرداند. دلیل این اتفاق این است که به جای تمرکز روی h2، این بار روی <div class="card-content"> تمرکز کرده ایم. تمامی اشیا کتابخانه Beautiful Soup  با استفاده از اتربیوت «.parent» ارائه می شوند. با استفاده از این روش عملیات وب اسکرپینگ با پایتون خیلی سریع تر از آن چیزی که فکر کنید انجام می شود و راهی بصری برای گذر از ساختار DOM و پیدا کردن آدرس عناصر مختلف ساخته می شود.

استخراج ویژگی ها از عناصر HTML

در آخرین مرحله از وب اسکرپینگ با پایتون؛ به  دنبال پیوند درخواست شغل هستیم. قبل از رسیدن به این مرحله اسکریپت پایتون؛ کد های HTML را خراش داده است و آگهی های مرتبط را فیلتر کرده است. اگر هنوز محتوای صفحات را نمی دانید و نیاز است که نیم نگاهی بیاندازید؛ این کار را حتما انجام دهید. آگهی های شغلی دارای دو لینک در قسمت پایین هستند.

for job_element in python_job_elements:
    # -- snip --
    links = job_element.find_all("a")
    for link in links:
        print(link.text.strip())

اگر این قطعه کد را اجرا کنید؛ به جای URL های مرتبط؛ متن لینک را دریافت می کنید که علت آن نیز استفاده از اتربیوت text. استفاده کرده ایم و این اتربیوت نیز فقط متن های موجود در HTML را بر می گرداند نه آن چیزی که انتظارش را دارید.

<!-- snip -->
    <footer class="card-footer">
        <a href="https://www.realpython.com" target="_blank"
           class="card-footer-item">Learn</a>
        <a href="https://realpython.github.io/fake-jobs/jobs/senior-python-developer-0.html"
           target="_blank"
           class="card-footer-item">Apply</a>
    </footer>
  </div>
</div>

URL لینک ها با عنصر href در ارتباط است. اگر به دنبال URL خاصی هستید؛ باید مقدار اتربیوت  href تگ دوم <a> در پایین کد های HTML یک پست شغلی را استخراج کنیم. در این لحظه از عملیات وب اسکرپینگ با پایتون؛ با واکشی تمام عناصر  تگ <a> در یک موقعیت شغلی شروع می کنیم و مقدار ویژگی های href آن ها را با استفاده از علامت براکت استخراج می کنیم:

for job_element in python_job_elements:
    # -- snip --
    links = job_element.find_all("a")
    for link in links:
        link_url = link["href"]
        print(f"Apply here: {link_url}\n")

در قطعه کد بالا؛ ابتدا همه لینک ها را از تمامی آگهی های شغلی استخراج کردیم. سپس ویژگی href را که حاوی URL است مطابق با دستورات استخراج کردیم و آن را در کنسول خود به نمایش گذاشتیم.

خلاصه ای درباره وب اسکرپینگ با پایتون

بالاخره آموزش وب اسکرپینگ با پایتون به اتمام رسید و الحق و الانصاف که کامل ترین آموزش متنی وب اسکرپینگ در پایتون است. اگر مرحله به مرحله با این آموزش پیش بروید؛ مطمئن باشید فرآیند وب اسرپینگ با موفقیت انجم می شود و می توانید از هر سایتی که بخواهید؛ دیتای مورد نظر خود را استخراج کنید. توصیه من به شما تمرین کردن است.

تبدیل شدن به یک برنامه نویس حرفه ای اتفاق نمی افتد مگر با تمرین و تکرار زیاد. اگر می خواهید صفر تا صد پایتون و به طور ویژه وب اسکرپینگ با پایتون را به صورت کاملا حرفه ای یاد بگیرید؛ می توانید از آموزش های دوره بزرگ استادی پایتون استفاده کنید.  امیدوارم از این آموزش استفاده کنید.

اگر سوال، نظر یا پیشنهادی داشتید؛ حتما کامنت بگذارید. اگر تجربه web scraping دارید؛ آن را با ما به اشتراک بگذارید و بگویید این کار را با چه زبان برنامه نویسی انجام دادید و چقدر طول کشید تا صفر تا صد این فرآیند را انجام دهید.