"آن کس که نداند و بداند که نداند" هستم
دیوونه بازی با پایتون : کتابخانه ریجکس!!
تا حالا براتون پیش اومده که بخواین یک رشته رو پردازش کنید؟
آموزش رو با یک سوال شروع کردم. یک سوال سرنوشت ساز! چون هر برنامه نویسی باید کتابخانه Regex رو بلد باشه.
شاید خوشحال بشید؛ شاید هم ناراحت! برای اینکه میخوام این آموزش رو پروژه محور جلو ببرم. یعنی میخوایم یک هدف برای خودمون مشخص کنیم؛ همینطور که به هدف نزدیک تر میشویم، به یادگیری بهتر هم دست مییابیم.(رسمی صحبت کردن، حس خوبی میده!)
پروژه که میخواین درستش کنیم چیه؟
بعضی از سایت ها هستن که اطلاعاتی رو به برنامه نویس ها میدن. یعنی با دادن یک api، برنامه نویس میتونه اطلاعات سایت رو بگیره. ولی بعضی از سایت ها هستن که api به برنامه نویس ها نمیدن. مثلا سایت بورس تهران یا سایت time.
وبسایت time.ir
یکم با api آشناشین
امروز میخوایم با کمک کتابخانه ریجکس و requests، وارد سایت time.ir بشیم و از توی کد سایت time.ir، تاریخ شمسی رو استخراج کنیم!
مرحله اول - دریافت کد سایت
در اولین مرحله، کتابخانه های لازم رو صدا میکنیم.
import requests
import re
تعجب نکنید!! کتابخانه re، خلاصه شده همون ریجکسه.
در مرحله بعدی باید کد سایت رو با استفاده از کتابخانه requests، دریافت کنیم.
r = requests.get('https://www.time.ir')
اگر r رو پرینت کنیم، باید با خروجی زیر روبرو شویم :
<Response [200]>
اگر با خروجی بالا روبرو شدین، یعنی همه چی درسته و میتونین وارد سایت بشین. اگر نشدین، پس یعنی صددرصد با یکی از حالت های زیر روبرو شدین(البته باید یادتون باشه که به اینترنت وصل باشید:D)
حالا اگر کد سایت رو بخوایم چاپ کنیم، باید از دستور زیر استفاده کنیم:
r = r.text
خروجی کد بالا اینه:
<!DOCTYPE html>
<html lang='fa' xml:lang='fa' itemscope itemtype="http://schema.org/WebPage">
<head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport"......
دیگه بقیش رو نمینویسم(1600 خطه!)؛ چون اصلا لازم نیست. همینطور که توی این کد میچرخیم، با این کد روبرو میشیم:
<div class="text-center">
<div class="dateTypeTitle">
<span
id="ctl00_cphTop_Sampa_Web_View_TimeUI_ShowDate00cphTop_3734_lblShamsiTitle"
class="show title">شمسی</span>
</div>
<div class="dateTypeBody">
<span id="ctl00_cphTop_Sampa_Web_View_TimeUI_ShowDate00cphTop_3734_lblShamsiNumeral" class="show numeral">۱۳۹۹/۰۱/۲۶</span>
توی کد بالا کلمه "شمسی" و تاریخ امروز وجود داره.(یکم بگردین:)) اگر پیدا کردین، آفرین?
آموزش کتابخانه Regex
یه همچین عددی رو فرض کنید:
149853301250910845287515529568796939729530823567627077867753375684694751845499010198513288240806185488720405794322901755334701505375868241863652321086085464175146674675647227094711698630265397174162942203787811947725632161269061623190529887376840005563889752962138977116240676380579516412977985064270
حتی فرض کردنشم سخته! حالا من ازتون یه سوال دارم. همه اعدادی سه رقمی رو که رقم اولشون(صدگان) 2 هست رو از توی عدد بالا پیدا کنید! من که اصلا حس شمردنشون رو ندارم. پس واجب شد regex رو یاد بگیریم. کتابخونه regex(قسمت findall) کل این کار هارو بدون هیچ دردسری انجام میده. میدونی بیل گیتس چی میگه؟
بیل گیتس میگه : همیشه سخت ترین کار هارو به تنبل ترین آدم ها بده! اونا ساده ترین راه رو براش پیدا میکنن.
با یه مثال ساده میخوایم findall رو در ریجکس رو یاد بگیریم. همونطور که از اسمش معلومه، تابع findall برای پیدا کردن یک الگو است. به کد زیر یه نگاهی بیاندازید:
import re
text = 'salam'
res = re.findall('[a-z]a', text)
برنامه بالا همه کلماتی را که دو حرفی هستند و حرف دومشان a هست را برای ما پیدا میکند. یعنی میگیم اولین حرف از a تا z باشد و حرف دوم هم a باشد.
خروجی
output : ['sa', 'la']
حالا با چیزی که یاد گرفتیم، میخوایم همه اعداد سه رقمی که رقم اولشان(صدگان) 2 است را از اون عدد خفنه پیدا کنیم.
اول که باید کتابخانه ریجکس رو صدا کنیم.
import re
بعدش باید یه متغییر تعریف کنیم و اون عدده رو توش بریزیم.
text = '149853301250910845287515529568796939729530823567627077867753375684694751845499010198513288240806185488720405794322901755334701505375868241863652321086085464175146674675647227094711698630265397174162942203787811947725632161269061623190529887376840005563889752962138977116240676380579516412977985064270'
حالا باید با چیزی که یاد گرفتیم، همه اعداد سه رقمی که.... رو پیدا کنیم.
res = re.findall('2[0-9][0-9]', text)
خروجی
output : ['250', '287', '295', '295', '235', '270', '288', '240', '204', '229', '241', '232', '227', '265', '294', '220', '256', '216', '269', '231', '298', '296', '213', '240', '297', '270']
دیدین چقدر ساده بود؟
خدا یا اگه تنبل نبودم باید چیکار میکردم؟
مطمئنا الان همتون این شکلی شدین:
ولی باید بگم تازه این اول راهه:D
بریم سراغ مسئله اصلی. یعنی همون در آوردن تاریخ شمسی از توی سایت time.ir.
آخرین کدی که زده بودیم این بود که کد سایت رو برامون در میآورد.
import requests
import re
r = requests.get('https://www.time.ir/')
r = r.text
خب حالا وقتشه که با استفاده از findall در ریجکس، تاریخ شمسی رو از توی سایت دربیاریم.
import requests
import re
r = requests.get('https://www.time.ir/')
r = r.text
halat_haye_momken = '[0-9][0-9][0-9][0-9]/[0-2][0-9]/[0-3][0-9]'
date = re.findall(halat_haye_momken, r)
date_shamsi = date[2]
print(date_shamsi)
خروجی
output : 1398/01/29
به همین سادگی!
حالا میخوایم با استفاده از این کد و کتابخانه easygui، یک برنامه گرافیکی بسازیم.
اینم از آموزش کتابخانه easygui
همه برنامه کد قبلی رو میبریم توی یه تابع:
def get_web():
r = requests.get('https://www.time.ir/')
r = r.text
date = re.findall('[0-9][0-9][0-9][0-9]/[0-2][0-9]/[0-3][0-9]', r)
date_shamsi = date[2]
return date_shamsi
date = get_web()
main_page = easygui.msgbox('What date is today?', "Today's date", 'I do not know. tell me!')
date_page = easygui.msgbox('Today is ' + date, "Today's date", 'OK. I understood')
مطلبی دیگر از این انتشارات
چطور توی پایتون بازی بسازیم؟ - قسمت ششم
مطلبی دیگر از این انتشارات
یه کوچولو وب اسکرپینگ با پایتون:) (۳)
مطلبی دیگر از این انتشارات
چطور توی پایتون بازی بسازیم؟ - قسمت پنجم