در مطلب های پیشین در مورد وب اسکریپنگ در پایتونبرای استخراج داده های وب، بوسیله کتابخانه bs4 صحبت کرده ایم. در این مطلب می خواهیم جنبه دیگری از وب اسکرپینگ برای بدست آوردن آمار جمعیت کشورها درسال ۲۰۱۸ را آموزش دهیم. در این مطلب از کتابخانه های bs4 و Pandas و SqlAlchemy استفاده شده است تا بتوانیم جدول رده بندی کشورها بر اساس جمعیت را از اینجا استخراج و سپس درون یک جدول پایگاه داده ذخیره کنیم. شکل زیر جدول لینک مربوطه را نشان می دهد.

در شکل زیر ماژول ها و توابع و کلاس های لازم از هر کدام به درون فایل برنامه ضمیمه شده اند. سپس همانند مطلب های پیشین از متد ()urloprn از کتابخانه urllib.request برای باز کردن و خواندن محتوای صحفه ذخیره شده در متغیر url استفاده شده است. در صورتی که صفحه با موفقیت خوانده شود، شی soup از کلاس BeatifulSoup ایجاد شده و سپس توسط دستور soup.title.string مقدار تگ title اچ تی ام ال یا همان عنوان صحفه خوانده می شود. قاعدتا خواندن عنوان صفحه به شما کمک می کند که بدانید رده بندی جمعیت کشورها را برای کدام سال بدست آورده اید.

مثال – خواندن جدول رده بندی و بدست آوردن تمامی لینک های ستون نخست

در شکل زیر نخست بوسیله متد ()find جدول یا تگ tbody از درون صفحه وب، استخراج می شود. سپس یک نوع دیکشنری در پایتون به نام links ایجاد می شود که می خواهیم کلیدهای آن نام کشورها و مقدار هر کلید لینک در سایت http://www.worldometers.info باشد که آمار سال های پیش به ازای هر کشور را نگه می دارد. به طور مثال اینجا آمار جمعیت سال های پیش برای کشورمان را نشان می دهد. درون یک حلقه for و بوسیله متد ()find_all وتا زمانی که تگ tr وجود داشته باشد، گام به گام تمامی تگ های a درون متغیر link ریخته شده و سپس خصوصیت href آنها استخراج می شوند.

چون می خواهیم کلید هر عنصر دیکشنری نام کشور باشد، پس از درون از فرمان ()link.get_text استفاده شده است و برای بدست آوردن مقدار خصوصیت href تگ a از فرمان [‘link[‘href استفاده شده است سپس مقدار [‘link[‘href با آدرس پایه سایت، یعنی http://www.worldometers.info پیوند داده شده است، زیرا مقدار href تگ های a در ستون نخست جدول، به طور مثال به صورت world-population/iran-population/ است.

مثال – بدست آورن تمامی ستون های جدول و نگهداری آنها در یک لیست

در کد شکل زیر نخست و بوسیله متد ()find_all تمامی تگ های tr خوانده می شوند. برای این کار مانند مثال پیش، از متد ()find_all استفاده شده تا تگ های tr درون متغیر table را بخوانیم، زیرا متغیر table که پیش از این بوسیله فرمان (‘soup.find(‘tbody ایجاد شده بود شامل تمامی محتوای تگ tbody است. سپس یک لیست به نام population ایجاد می کنیم و درون یک حلقه for تا زمانی که به عنصر پایانی لیست برسیم، نخست تمامی تگ های td بدست آمده و سپس توسط متد ()strip تمامی فضاهای خالی پاک شده درنهایت ستون cols به لیست populate الحاق می شود. توجه کنید که در هر گام متغیر cols یک لیست برابر با یک سطر از جدول است و در پایان متغیر population یک لیست از لیست ها خواهد بود که در شکل زیر نشان داده شده است.

ایجاد Dataframe از متغیر population

پس بدست آوردن فهرست تمامی سطرهای جدول، به منظور پیش پردازش داده های درون جدول، از روی متغیر population یک Dataframe ایجاد می کنیم. در پیوندهای زیر در مورد ایجاد DataFrame در پایتون بوسیله کتابخانه Pandas صحبت شده است. شکل زیر ساختار Dataframe را نشان می دهد که آنرا در همان متغیر population ذخیره کرده ایم. همانطور که می بینید لازم است مقدار برخی از ستون ها به منظور ذخیره سازی در پایگاه داده، پالایش شوند. به طور نمونه ستون پایانی کاراکتر % دارد که باید حذف شود و ستون دوم (اندازه جمعیت) عددهایی هستند که میان عددهای آن ویرگول وجود دارد.

نمایش یکپارچه داده در پایتون توسط DataFrame

ایجاد DataFrame توسط ماژول Pandas در پایتون

همانطور که در شکل بالا می بینید نام ستون ها به صورت عددی است و این به هیچ عنوان برای نمایش داده ها مناسب نیست، پس مطابق کدهای زیر یک لیست از نام ستون ها را به خصوصیت columns از DataFrame به نام population انتساب می دهیم و سپس مطابق شکل زیر خواهید دید که دیگر در نمایش Dataframe ستون ها دارای نام هستند. همچنین در کنار داشتن نام برای نمایش، در ادامه خواهید دید که از نام های ستون برای اشاره و دسترسی به آنها استفاده خواهیم کرد.

مطابق شکل بالا ستون row که شماره سطرهای جدول را نشان می دهد، لازم نیست که در پایگاه داده ذخیره شود، پس مطابق کد شکل زیر آنرا توسط متد ()drop پاک می کنیم. توجه کنید متد ()drop عضو کلاس DataFrame در کتابخانه Pandas است، پس از طریق متغیر DataFrame به نام population به آن دسترسی پیدا کرده ایم. در متد ()drop پارامتر labels لیستی از نام ستون های DataFrame را دریافت می کند که می خواهیم یک باره کل ستون ها از DataFrame پاک شوند. پارامتر axis برابر با عدد 1 است و به معنی که ستون های لیست پارامتر labels یکباره حذف شوند.

پالایش داده ها

در داده های جدول و قاعدتا در DataFrame و به طور مثال در ستون Population، داده های نامناسبی برای ذخیره سازی در جدول وجود دارند. به طور مثال در ستون Population میان عددها کاراکتر ویرگول و در ستون پایانی کاراکتر % در عدد وجود دارد ولی چون می خواهیم این مقدارها را در ستون های جدول مربوطه که از نوع عدد صیحیح است ذخیره کنیم، پس می بایست توسط دستورهای شکل زیر تک تک داده های معیوب از جدول حذف شوند.

توجه کنید در کدهای زیر تابع های ()str.replace از کلاس Series هستند. هر ستون از یک DataFrame را یک Series می گویند و در Pandas متدهایی وجود دارند که می توان آنها را روی داده های یک Series اعمال کنیم. به طور مثال ()str.replace کاراکتر یا رشته پارامتر دوم را جایگزین پارامتر نخست می کند. به طور مثال نخستین اجرای ()str.replace در کدهای زیر، کاراکتر ویرگول را از میان عددهای ستون Population حذف می کند.

ایجاد پایگاه داده بوسیله SqlAlchemy

در مطلب های مرتبط با دوره برنامه نویسی پایگاه داده با SqlAlchemy در مورد کتابخانه SqlAlchemy صحبت شده است. کدهای زیر یک جدول ساده را ایجاد می کند که هر ستون آن یکی از ستون های DataFrame را در خود نگه می دارد. پیش از هر چیز می بایست یک رشته اتصال را بوسیله متد ()create_engine ایجاد کنید. همچنین لازم است تا یک پایگاه داده که در این مطلب webscraping نام دارد را در پایگاه داده (در اینجا MySQL) ایجاد کنید. سپس مطابق با کلاس CountryPopulation یک جدول در پایگاه داده ایجاد خواهد شد.

سپس مطابق کدهای زیر نخست جدول ایجاد می شود و سپس از متد ()to_sql برای درج سطر های DataFrame به درون ستون های جدول استفاده کردیم. سپس برای آزمایش و اطمینان از درج سطرهای DataFrame درون ستون های جدول، از متدهای کتابخانه SqlAlchemy برای واکشی داده ها و شبیه سازی عبارت SELECT استفاده شده است.

دسترسی به جدول در پایگاه داده بوسیله SqlAlchemy

کوئری SELECT بر روی جدول ها در SqlAlchemy

عبارت شرطی WHERE در SqlAlchemy بخش نخست

عبارت شرطی در SqlAlchemy بخش دوم

ایجاد جدول در SqlAlchemy

دانلود سورس برنامه این مطلب Bs4 Pandas SqlAlchemy