در این مقاله ابتدا به بررسی API-های سطح بالا میپردازیم و در ادامه با ماهیت، طرز کار، شیوه استفاده در کد و روش سازماندهیشان آشنا میشویم. همچنین نگاهی خواهیم داشت به کلاسهای اصلی متفاوت API-های وب و کاربردهای مختلفی که دارند.
API اختصاری برای عبارت «رابط برنامهنویسی اپلیکیشن» (Application Programming Interfaces) است و سازهای است که در اختیار زبانهای برنامهنویسی قرار میگیرد تا بتوانند کارکردهای پیچیده را به روش آسان ایجاد کنند. API-ها کدهای پیچیده را از شما انتزاع میکنند و در وهله نخست ساختار آسانی برای کار کردن در اختیار شما قرار میدهند.
نکته: برای مطالعه قسمت قبلی این مجموعه مطالب آموزشی میتوانید به این لینک رجوع کنید: انتخاب رویکرد مناسب در برنامه نویسی ناهمگام جاوا اسکریپت — راهنمای جامع
به عنوان یک مثال واقعی میتوانید جریان برق یک خانه، آپارتمان یا دیگر ساختمانها را تصور کنید. اگر بخواهید از لوازم خانه استفاده کنید، باید آنها را به پریز برق وصل کنید تا به کار بیفتند. شما تلاش نمیکنید که برق را به نقاط مختلف خانه سیمکشی کنید، چون این کار میتواند کاملاً ناکارآمد باشد و در صورتی که برقکار نباشید، تلاش خطرناک و دشواری نیز محسوب میشود.
به ترتیب مشابه اگر بخواهید برخی گرافیکهای 3 بعدی را برنامهنویسی کنید، استفاده از API-های نوشته شده در زبانهای سطح بالا مانند جاوا اسکریپت یا پایتون بسیار آسانتر از نوشتن کدهای سطح پایین (مانند C یا ++C) است که مستقیماً GPU رایانه را کنترل میکنند یا کارکردهای گرافیکی دیگری را ارائه میکنند.
جاوا اسکریپت سمت کلاینت به طور خاص API-های زیادی در اختیار ما قرار داده است که بخشی از خود زبان جاوا اسکریپت نیستند، بلکه بر مبنای زبان اصلی جاوا اسکریپت ساخته شدهاند و امکانات فوقالعادهی اضافی برای استفاده در کدهای جاوا اسکریپت ارائه میکنند. این API-ها عموماً در دو دسته جای میگیرند که در ادامه به این دو دسته خواهیم پرداخت.
این API-ها بر مبنای مرورگر ساخته میشوند و امکان افشای دادهها را از مرورگر و محیط پیرامونی رایانه فراهم میسازند و کارهای مفید پیچیدهای انجام میدهند. برای نمونه، Web Audio API سازههای جاوا اسکریپت را برای دستکاری صدا در مرورگر ارائه میکنند. بدین ترتیب میتوان یک قطعه صوتی را ضبط کرد، صدا را کاهش یا افزایش داد، جلوههایی روی آن اعمال کرد و مواردی از این دست. مرورگر در پسزمینه عملاً از کدهای پیچیده سطح پایینی (مانند ++C یا Rust) برای پردازش واقعی صداها استفاده میکند، اما در این مورد نیز پیچیدگی از طریق API انتزاع شده است.
این دسته از API-ها به صورت پیشفرض در مرورگر موجود نیستند و کدهای آنها را عموماً باید از جای دیگری در وب استخراج کنیم. برای نمونه، Twitter API امکان اجرای کارهایی مانند نمایش دادن آخرین توییت ها روی وبسایت فراهم میسازد. بدین ترتیب مجموعه خاصی از سازهها در دسترس ما قرار میگیرد که میتوان به سرویس توییتر کوئری زد و اطلاعات خاصی را به دست آورد.
در بخش قبل در مورد این که API-های سمت کلاینت جاوا اسکریپت چه هستند و چه ارتباطی با زبان جاوا اسکریپت دارند صحبت کردیم. در این بخش مباحث مطرح شده را جمعبندی میکنیم تا همه چیز روشنتر شود و نقش ابزارهای دیگر جاوا اسکریپت نیز مشخص شود.
جاوا اسکریپت: یک زبان اسکریپتنویسی سطح بالا است که بر مبنای مرورگرها ساخته شده است و امکان پیادهسازی کارکردهای روی صفحهها و اپلیکیشنهای وب را به دست میدهد. توجه کنید که جاوا اسکریپت در محیطهای برنامهنویسی دیگر مانند Node نیز عرضه شده است.
API-های مرورگر: سازههایی هستند که بر مبنای مرورگر ساخته شدهاند و روی زبان جاوا اسکریپت کار میکنند و امکان پیاده سای آسانتر کارکردها را فراهم میسازند.
API-های شخص ثالث: سازههایی هستند که در پلتفرمهای شخص ثالث (مانند توییتر، فیسبوک و غیره) ساخته شدهاند و میتوان آنها را به صفحه وب الحاق کرد تا برخی از امکانات آن پلتفرمها در صفحههای وب شخصی ارائه شوند. برای نمونه میتوان آخرین توییتها را در صفحه وب شخصی نمایش داد.
کتابخانههای شخص ثالث: معمولاً یک یا چند فایل جاوا اسکریپت هستند که شامل تابعهای سفارشی هستند و به صفحه وب الحاق میشوند تا نوشتن کارکردهای رایج را تسریع یا فعالسازی کنند. نمونههایی از آن شامل jQuery، Mootools و React است.
فریمورکهای جاوا اسکریپت: فریمورکها بر مبنای کتابخانهها ساخته میشوند، فریمورکهای جاوا اسکریپت مانند انگولار و Ember در واقع پکیجهای HTML ،CSS و جاوا اسکریپت و دیگر فناوریهایی که نصب میشوند هستند و سپس برای نوشتن وباپلیکیشنها از صفر مورد استفاده قرار میگیرند. تفاوت کلیدی بین کتابخانه و فریمورک در «معکوس شدن کنترل» است. زمانی که یک متد از یک کتابخانه فراخوانی میشود، توسعهدهنده مسئول کنترل آن است. در یک فریمورک کنترل معکوس میشود، یعنی فریمورک، کد توسعهدهنده را فراخوانی میکند.
تعداد بسیار زیادی از API-ها در مرورگرهای مدرن وجود دارند که امکان انجام طیف گستردهای از کارها را در کد فراهم میسازند. با ملاحظه صفحه اندیس API-های MDN (+) این مسئله واضحتر دیده میشود.
API-های مشترک مرورگر: به طور خاص، دستهبندیهای رایجتر API-های مرورگر که مورد استفاده قرار میگیرند به شرح زیر هستند:
API-ها برای دستکاری اسناد: این API-ها در مرورگر بارگذاری میشوند. بدیهیترین مثال API مربوط به DOM است که امکان دستکاری HTML و CSS را میدهد. به وسیله این API میتوان کدهای HTML را به صورت دینامیک ایجاد، یا حذف کرده و یا تغییر داد و استایلهای جدیدی روی صفحه اعمال کرد. هر بار که در هنگام مرور وب یک پنجره پاپآپ میبینید یا نوعی محتوای جدید روی صفحه ظاهر میشود DOM عمل کرده است.
API-هایی که دادهها را از سرور واکشی میکنند: این API-ها بخشهای کوچکی از صفحه وب را که کاربرد بیشتری دارند، بهروزرسانی میکنند. این جزییات به ظاهر کوچک تأثیر زیادی روی عملکرد و رفتار سایتها دارند. اگر صرفاً لازم باشد که یک فهرست انبار یا فهرستی از موجودی جدید بهروزرسانی شود، انجام این کار به صورت مستقیم بدون نیاز به بارگذاری مجدد کل صفحه از سرور موجب میشود که سایت یا اپلیکیشن واکنشگرایی بیشتری به نمایش بگذارد و کارآمد به نظر برسد. API-هایی که این امر را ممکن میسازند، شامل XMLHttpRequest و Fetch API هستند. همچنین ممکن است با Ajax مواجه شده باشید که این تکنیک را توضیح میدهد.
API-هایی برای رسم و دستکاری گرافیکها: این API-ها اینک به صورت گسترده از سوی مرورگرها پشتیبانی میشوند. رایجترین انواع این API-ها شامل Canvas و WebGL هستند که امکان بهروزرسانی برنامهنویسی شده دادههای پیکسلی موجود در عنصر <canvas> در HTML را به صورت صحنههای 2 و 3 بعدی فراهم میسازند. برای نمونه میتوان شکلهایی از قبیل مستطیل یا دایره را روی صفحه رسم کرد، یک تصویر را در یک بوم ایمپورت کرد و یک فیلتر مانند «حالت قهوهای» (Sepia) یا «سیاه و سفید» (grayscale) را با استفاده از Canvas API روی آن اعمال کرد. همچنین میتوان یک صحنه 3 بعدی پیچیده را به همراه نوردهی و بافتها با کمک WebGL روی صفحه ایجاد کرد. چنین API-هایی غالباً با API-های مربوط به ایجاد حلقههای انیمیشن مانند ()window.requestAnimationFrame و همچنین API-های دیگر برای بهروزرسانی مداوم صحنههایی مانند کارتون یا گیم ترکیب میشوند.
API-های صوتی و ویدئویی: این API-ها از قبیل HTMLMediaElement ،the Web Audio API و WebRTC امکان اجرای کارهای واقعاً جذابی را با فایلهای چندرسانهای فراهم میسازند. از جمله کارهایی که این API-ها انجام میدهند شامل ایجاد کنترلهای UI سفارشی برای پخش صوت و ویدئو، نمایش مسیرهای متنی مانند عنوان و زیرنویس همراه فیلم، دریافت ویدئو از دوربین وب و دستکاری آن از طریق یک بوم یا نمایش روی نمایشگر یک فرد دیگر برای اجرای ویدئوکنفرانس و یا افزودن جلوههایی به قطعههای صوتی است.
API-های دستگاه: این API-ها اساساً برای دستکاری و بازیابی دادهها از سختافزار دستگاههای مدرن به ترتیبی که برای وباپلیکیشنها مفید باشند، مورد استفاده قرار میگیرند. نمونههایی از آن چنین است که از طریق بخش نوتیفیکیشنهای سیستم به کاربر اعلام کنیم که یک بهروزرسانی مفید برای وب اپلیکیشن موجود است یا از سختافزار ویبره دستگاه استفاده کنیم.
API-های ذخیرهسازی سمت کلاینت: این API-ها به تدریج در مرورگرهای وب بسیار گسترش مییابند، چون امکان ذخیرهسازی دادهها در سمت کلاینت در صورتی که بخواهید یک اپلیکیشن بسازید که «حالت» (State) را بین بارگذاری صفحههای مختلف حفظ کند و احتمالاً حتی وقتی دستگاه آفلاین است، کار کند، بسیار مفید خواهد بود. چند گزینه مانند ذخیرهسازی ساده نام/مقدار با و ذخیرهسازی جدولی پیچیدهتر دادهها با استفاده از IndexedDB API به این منظور وجود دارند.
API-های مشترک شخص ثالث: API-های شخص ثالث در طیف گستردهای عرضه شدهاند. برخی از انواع رایجتر شامل آنهایی میشوند که هر توسعهدهندهای دیر یا زود باید مورد استفاده قرار دهد.
API-های مختلف جاوا اسکریپت به روشهای نسبتاً متفاوتی عمل میکنند، اما طرز کار آنها عموماً دارای ویژگیها و طرحبندیهای مشابهی است.
کد شما با استفاده از یک یا چند شیء جاوا اسکریپت با API-ها تعامل مییابد که به عنوان کانتینرهایی برای دادههایی که API استفاده میکند (در مشخصههای شیء) و کارکردی که API مهیا میکند (در متدهای شیء)، عمل میکنند.
اگر به مثال API وب صوتی بازگردیم میبینیم که این یک API نسبتاً پیچیده است که شامل تعدادی شیء است. بدیهیترین آنها شامل موارد زیر هستند:
اینک سؤال این است که این اشیا چگونه تعامل مییابند؟ در قطعه کد زیر مثالی از یک پخشکننده صدا ارائه شده است:
در نخستین بخش این کد با HTML زیر مواجه میشویم:
قبل از هر چیز عنصر <audio> را include میکنیم و با آن یک فایل MP3 را در صفحه جاسازی میکنیم. ما هیچ کنترل پیشفرض مرورگر را نگنجاندهایم. سپس یک عنصر <button> قرار دادهایم که از آن برای پخش و قطع صدا استفاده میکنیم. همچنین یک عنصر <input> از نوع range قرار دادهایم که برای تنظیم شدت صدای در حال پخش استفاده میشود.
سپس به کد جاوا اسکریپت این مثال نگاه میکنیم. کار خود را با ایجاد یک وهله از AudioContext آغاز میکنیم که درون آن به دستکاری قطعه صوتی میپردازیم:
سپس ثابتهایی میسازیم که ارجاعها به عناصر <audio> ،<button> و <input> را نگهداری میکنیم. از متد ()AudioContext.createMediaElementSource برای ایجاد یک MediaElementAudioSourceNode استفاده میکنیم که نماینده منبع صدای ما است. عنصر <audio> که صدا از آن پخش میشود به صورت زیر است:
در ادامه یک جفت دستگیره رویداد میگنجانیم تا زمانی که دکمه کلیک شود بین حالتهای پخش و توقف تغییر پیدا میکنند. همچنین زمانی که پخش قطعه صوتی به انتها برسد، آن را به ابتدای قطعه ریست میکنند:
نکته: ممکن است متوجه شده باشید که متدهای ()play و ()pause که برای پخش و مکث قطعه صوتی استفاده میشوند بخشی از API صوتی وب نیستند. در واقع آنها بخشی از API به نام HTMLMediaElement هستند که گرچه متفاوت است اما ارتباط نزدیکی دارد.
سپس یک شیء GainNode با استفاده از متد ()AudioContext.createGain میسازیم که از آن میتوان برای تنظیم شدت صدا استفاده کرد و یک دستگیره رویداد دیگر میسازیم که هر زمان مقدار اسلایدر تغییر یابد، مقدار شدت صدا را تغییر میدهد.
آخرین کاری که برای عملیاتی کردن این پخشکننده صوتی لازم است، اتصال گرههای مختلف به گراف صوتی است که با استفاده از متد ()AudioNode.connect روی هر نوع از گره صورت میگیرد:
صدا در منبع آغاز میشود که در ادامه به گره gain متصل شده است تا بتوان شدت صدا را تنظیم کرد. گره gain به گره مقصد وصل شده است تا بتوان صدا را روی رایانه پخش کرد.
زمانی که از API استفاده میکنید باید مطمئن شوید که میدانید نقطه ورود API کجاست. در API صوتی وب این نقطه ورود کاملاً مشخص و شیء AudioContext است که باید برای انجام هر نوع دستکاری صوتی استفاده شود.
API مربوط به مدل شیء سند یا DOM نیز نقطه ورود سادهای دارد. قابلیتهای آن را میتوان در شیء Document یا یک وهله از عنصر HTML یافت که به نحوی میخواهید عملیاتی کنید. برای نمونه:
Canvas API نیز روی دریافت یک شیء context برای استفاده جهت دستکاری موارد مختلف استوار است، گرچه در این مورد به جای یک context صوتی یک context گرافیکی وجود دارد. شیء context آن از طریق دریافت یک ارجاع به عنصر <canvas> که قرار است روی آن ترسیم کنیم ایجاد میشود و سپس متد ()HTMLCanvasElement.getContext آن فراخوانی میشود:
هر کاری که بخواهیم روی بوم انجام دهیم از طریق فراخوانی متدها و مشخصههای یک شیء context ممکن خواهد بود که وهلهای از CanvasRenderingContext2D است. برای نمونه:
برخی API-های وب شامل هیچ رویدادی نیستند، اما اغلب آنها دستکم چند رویداد دارند. مشخصههای دستگیره به ما امکان میدهند که تابعها را زمانی که رویدادها اتفاق میافتند اجرا کنیم.
ما در مثال فوق برخی از دستگیرههای رویداد را که در API صوتی وب استفاده میشوند مشاهده کردیم. برای ارائه مثالی دیگر باید بگوییم که وهلههای شیء XMLHttpRequest هر یک نماینده یک درخواست HTTP به سرور هستند که نوعی منابع جدید را بازیابی میکنند و هر یک چندین رویداد دارند. برای نمونه رویداد load زمانی وقوع مییابد که یک پاسخ با موفقیت بازگشت یابد و شامل منبع درخواستی ناموجودی باشد.
کد زیر نمونه سادهای از شیوه استفاده از این رویداد را نشان میدهد:
چند خط نخست، موقعیت منبعی را که میخواهیم واکشی کنیم نشان میدهد، یک وهله جدید از شیء درخواست را با استفاده از سازنده ()XMLHttpRequest ایجاد میکند، یک درخواست HTTP به صورت GET باز میکند تا منبع موردنظر را بازیابی کند، پاسخی که باید ارسال شود را در قالب JSON تعیین میکند و سپس درخواست را ارسال میکند.
در ادامه تابع دستگیره onload، کاری را که با پاسخ انجام میدهیم توصیف میکند. میدانیم که پاسخ با موفقیت و پس از الزام رویداد load بازگشت خواهد یافت، مگر این که خطایی رخ دهد. از این رو پاسخ را که شامل JSON بازگشتی است در متغیر superHeroes ذخیره میکنیم و سپس آن را به دو تابع مختلف برای پردازش بیشتر ارسال میکنیم.
قابلیتهای WebAPI همچون جاوا اسکریپت و دیگر فناوریهای وب در معرض ملاحظات امنیتی هستند، اما برخی اوقات سازوکارهای امنیتی اضافی تعریف میشوند. برای نمونه برخی از WebAPI-های مدرن تنها روی صفحههایی کار میکنند که روی HTTPS عرضه شده باشند، چون دادههای بالقوه حساسی را انتقال میدهند.
به علاوه برخی WebAPI-ها درخواست مجوز فعال شدن را در زمان فراخوانی در کد از کاربر میکنند. به عنوان نمونه Notifications API از طریق یک کادر محاورهای بازشونده از کاربر اجازه میخواهد:
API-های Web Audio و HTMLMediaElement در معرض سازوکارهای امنیتی به نام autoplay policy هستند. معنی این وضعیت آن است که در زمان بارگذاری صفحه نمیتوان به صورت خودکار به پخش صدا پرداخت و باید از طریق یک کنترل مانند دکمه از کاربر اجازه پخش صدا را گرفت. دلیل انجام این کار آن است که پخش خودکار صدا معمولاً بسیار آزاردهنده است و کاربران عموماً دوست ندارند چنین وضعیتی را تجربه کنند.
نکته: بسته به این که یک مرورگر تا چه حد سختگیرانه عمل میکند، این سازوکارهای امنیتی ممکن است یک نمونه کد را از کارکرد محلی نیز بازدارند، یعنی زمانی که یک فایل مثال محلی را به جای وبسرور در یک مرورگر روی سیستم خود باز میکنید، کار نکند. در زمان نوشتن این مقاله، مثال Web Audio API این نوشته روی مرورگر گوگل کروم کار نمیکرد و باید آن را روی گیتهاب آپلود میکردیم.
در پایان مطالعه این مقاله شما باید ایده خوبی از مفهوم API-ها، طرز کار آنها، و کاربردهایی که در کد جاوا اسکریپت دارند، به دست آورده باشید. احتمالاً هیجانزده هستید که شروع به استفاده جالبی از API-های خاص بکنید. در بخش بعدی اقدم به دستکاری سندها با استفاده از API مدل شیء سند یعنی DOM خواهیم کرد.
برای مطالعه قسمت بعدی این مجموعه مطلب آموزشی به لینک زیر رجوع کنید:
فریمورک وب لاراول از مزیت کتابخانه محبوب SwiftMailer برخوردار است که استفاده از آن آسان است و طیف متنوعی از درایورهای ایمیل ارائه کرده است. در همین راستا، در این مقاله قصد داریم به بررسی API ارسال ایمیل در لاراول بپردازیم.
لاراول یک کتابخانه پوششی بر روی کتابخانه SwiftMailer بنا میکند که مدیریت ایمیل را همزمان به کاری بسیار آسان و قابل پیکربندی تبدیل میکند. تنظیمات پیشفرض ایمیل را میتوانید در فایل config/mail.php مشاهده کنید:
هنگامی که از ارسال ایمیل صحبت میکنیم، لاراول از درایورهای مختلفی پشتیبانی میکند. چنان که میبینید MAIL_DRIVER پیشفرض به صورت stmp تنظیم شده است. اگر قصد دارید از درایور stmp برای ارسال ایمیل استفاده کنید، در این صورت به مجموع تنظیمات دیگری مانند MAIL_HOST ،MAIL_PORT ،MAIL_ENCRYPTION ،MAIL_USERNAME و MAIL_PASSWORD هم نیاز خواهید داشت.
از سوی دیگر اگر قصد دارید از درایور sendmail استفاده کنید، در این صورت باید مطمئن شوید که مسیر سیستم sendmail در فایل config/mail.php به مقدار صحیحی تنظیم شده است.
همچنین میتوانید آدرس from را که در زمان ارسال ایمیلها با کلید from استفاده میشوند، تنظیم کنید. در نهایت اگر میخواهید از رندرینگ ایمیل مبتنی بر Markdown استفاده کنید، میتوانید این تنظیمات را زیر کلید markdown تنظیم کنید.
نکته جالب دیگر این است که میتوانید از ارائهدهندگان سرویسهای ایمیل شخص ثالث مانند Mailgun ،Mandrill ،SES و SparkPost نیز استفاده کنید. اگر از یکی از این سرویسها استفاده میکنید، باید اطمینان حاصل کنید که تنظیمات مربوطه را در فایل config/services.php تعیین کردهاید.
بدین ترتیب یک مقدمه کوتاه در مورد تنظیمات مرتبط با API ایمیل در لاراول داشتیم. از این بخش به بعد قصد داریم یک مثال سفارشی را بررسی کنیم که روش ارسال ایمیلها را نمایش میدهد.
در این بخش، کلاس Mailable را میسازیم که برای ارسال ایمیل استفاده میشوند. کلاس Mailable مسئول ارسال ایمیلها با استفاده از mailer است که آن نیز در فایل config/mail.php پیکربندی شده است. در واقع لاراول از قبل یک دستور آرتیزان به صورت زیر دارد که امکان ایجاد یک قالب پایه را به ما میدهد:
این دستور یک قالب ایمیل خالی در آدرس app/Mail/DemoEmail.php ایجاد میکند که در قطعه کد زیر میتوانید آن را ببینید:
محتوای این فایل را با کدهای زیر جایگزین کنید:
دو متد مهم در کلاس mailable به نامهای construct__ و build وجود دارند که به صورت سراسری پیادهسازی میشوند. متد construct__ برای مقداردهی اشیایی استفاده میشود که در قالب ایمیل قرار است استفاده شوند. از سوی دیگر متد build برای مقداردهی مقادیر خاص ایمیل مانند from، قالب view، پیوست ایمیل و نظایر آن استفاده میشود.
در این مورد، شیء demo$ را به صورت یک آرگومان سازنده ارسال میکنیم و آن را به مشخصه عمومی demo انتساب میدهیم. در متد build یک پیکربندی بندی خاص ایمیل را مقداردهی میکنیم.
From برای تعیین آدرس ایمیلی استفاده میشود که در آدرس فرستنده ایمیل درج خواهد شد.
با استفاده از متد view میتوان قالب ایمیلی را تعیین کرد که در زمان ارسال کردن ایمیل با استفاده از کلاس mailable استفاده خواهد شد. در این مورد ما از mails.demo استفاده میکنیم و معنی آن این است که باید یک فایل قالب view در مسیر resources/views/mails/demo.blade.php بسازید.
سپس متد text برای راهاندازی نسخه متنی سادهای از یک قالب ایمیل استفاده خواهد شد.
چنان که قبلاً اشاره کردیم متد construct__ برای راهاندازی شیءهایی استفاده میشود که در قالب ایمیل استفاده میشوند. میتوان از متد with نیز استفاده کرد که امکان تنظیم دادههای view یک پیام را فراهم میسازند. سپس از متد attach برای الصاق یک تصویر به پیام استفاده میکنیم.
البته ما باید یک قالب ایمیل ایجاد کنیم که در زمان ارسال ایمیلها مورد استفاده قرار خواهد گرفت. در ادامه فایل resources/views/mails/demo.blade.php را با محتوای زیر ایجاد میکنیم:
همچنین یک نسخه متنی ساده از این فایل را در مسیر resources/views/mails/demo_plain.blade.php میسازیم:
بدین ترتیب کلاس mailable بنا به دلخواه ما تنظیم شده است، اما هنوز کار ما تمام نشده است، چون باید از یک facade به نام Mail برای ارسال عملی ایمیلها استفاده کنیم. در بخش بعدی در مورد شیوه استفاده از facade به نام Mail برای ارسال ایمیل با استفاده از DemoEmail در کلاس mailable که هم اینک ایجاد کردیم توضیح خواهیم داد.
در این بخش یک نمونه میسازیم که نشان میدهد چگونه میتوان از کلاس mailable ایجاد شده در مرحله قبلی استفاده کرد.
یک فایل کنترلر در مسیر app/Http/Controllers/MailController.php با محتوای زیر میسازیم:
لازم به اشاره است که ما Facede موجود در مسیر Illuminate\Support\Facades\Mail که برای ارسال ایمیل استفاده میشود را نیز در این فایل include کردهایم. در متد send گزاره زیر مسئول ارسال یک ایمیل با مقداردهی App\Mail\DemoEmail در کلاس Mailable است:
متد to در Facade به نام Illuminate\Support\Facades\Mail یک وهله از کلاس \Illuminate\Mail\PendingMail بازگشت میدهد که از قبل شامل یک mailer مناسب پیکربندی شده در فایل config/mail.php است.
در نهایت از متد send در کلاس Illuminate\Mail\PendingMail\ استفاده میکنیم که عملاً یک ایمیل را ارسال میکند.
برای تست کردن این پروژه نمونه، یک مسیر مرتبط را در فایل اضافه میکنیم:
در این مرحله میتوانید URL زیر را اجرا کنید تا ببینید که مطابق انتظار کار میکند:
از سوی دیگر اگر میخواهید قالبهای ایمیل خود را به سرعت و بدون ارسال واقعی ایمیل تست کنید، شرایطی در لاراول تدارک دیده شده است که امکان لاگ کردن همه ایمیلهای خروجی را میدهد.
برای استفاده از این امکان باید مقدار MAIL_DRIVER را در فایل config/mail.php به log تنظیم کنید. سپس میتوانید URL فوقالذکر را اجرا کرده و فایل لاگ را بررسی کنید و ببینید که آیا قالب ایمیل در آنجا لاگ شده است یا نه.
اگر همه چیز به درستی پیش برود، باید ببینید که یک ایمیل در فایل storage/logs/laravel.log لاگ شده است. این همه آن چیزی است که در مورد قابلیت ایمیل در لاراول میتوان گفت و بدین ترتیب به انتهای این مقاله میرسیم.
در این مطلب به معرفی API ایمیل پرداختیم که از قابلیتهای داخلی لاراول است و از گستره متنوعی از درایورهای ارسال ایمیل نیز پشتیبانی میکند. ما کار خود را با توضیح مفاهیم مقدماتی آغاز کردیم و کلاس mailable را پیادهسازی کردیم که یک جزء ضروری در API ایمیل در لاراول است. در انتها کلاس mailable را نیز با ایجاد یک کنترلر سفارشی تست کردیم تا طرز کار عملی آن را مشاهده کنیم.
اگر یک برنامهنویس هستید و میخواهید شروع به استفاده از گیت روی گیتهاب بکنید، بهترین مقاله را برای مطالعه انتخاب کردهاید. شما پس از مطالعه این مقاله و آشنایی با روش ساخت مخزن گیت هاب و همچنین شیوه استفاده از آن قادر خواهید بود یک پروژه گیتهاب را ایجاد کرده و روی آن کار کنید.
گیت یک نرمافزار اوپن سورس است که در سال 2005 از سوی لینوس تروالدز ایجاد شده است. این ابزار یک «سیستم کنترل نسخه» (Version Control System) است که در ابتدا برای هماهنگ کار چند توسعهدهنده روی کرنل لینوکس ساخته شده بود. سیستمهای کنترل نسخه زیادی مانند CVS ،SVN ،Mercurial و غیره وجود دارند، اما گیت امروزه به یک نرمافزار استاندارد برای کنترل نسخه تبدیل شده است.
اگر به تازگی وارد دنیای برنامهنویسی شدهاید، این واژهها معنای خاصی برای شما نخواهند داشت. با این حال، جای نگرانی نیست، چون با مطالعه این پاراگرف کوتاه خواهید دانست که سیستم کنترل نسخه یا به اختصار VCS دقیقاً به چه معنا است؟
کنترل نسخه یک سیستم مدیریتی است و تغییرهایی که روی فایلها یا مجموعهای از فایلها (برای نمونه یک پروژه کدنویسی) ایجاد میشوند را ردگیری میکند. توسعهدهندگان با کمک چنین سیستمی، میتوانند با یکدیگر همکاری کنند و به صورت مشترک یک پروژه را جلو ببرند.
یک سیستم انشعاب از سوی کنترل نسخه اجرا میشود که به توسعهدهندگان کمک میکند تا به صورت انفرادی روی یک وظیفه کار کنند. برای نمونه یک شاخه برای یک وظیفه یا یک شاخه برای یک توسعهدهنده. در ادامه همه تغییرهای ایجاد شده از سوی تیم در شاخه اصلی ترکیب میشوند.
همه تغییرهای ایجاد شده از سوی توسعهدهندگان ردگیری و در «سابقه» (history) ذخیره میشوند. ردگیری این تغییرهای ایجاد شده از سوی هر یک از اعضای تیم میتواند سودمند باشد.
اگر میخواهید شروع به استفاده از گیت بکنید، باید بدانید که کجا میتوانید ریپازیتوریهای خود را میزبانی کنید. پلتفرمهای میزبانی زیادی وجود دارند که میتوانید کد خود را به طور رایگان روی آنها میزبانی کنید. برخی گزینهها رایگان نیستند، اما شما به جز در موارد خاص، به اغلب آنها نیازی نخواهید داشت.
در ادامه سه مورد از محبوبترین سرویسهای میزبانی گیت را ملاحظه میکنید:
نکته: پلتفرمهای میزبانی به دو روش در دسترس هستند که یکی روش کلود (میزبانی آنلاین) و دیگری میزبانی مستقل روی سرور شخصی (میزبانی خصوصی) است.
گیت ابزاری غیر قابل چشمپوشی برای توسعهدهندگان محسوب میشود. در ادامه فهرستی از مزیتهای این ابزار را مشاهده میکنید:
بدین ترتیب با مزیتهای عمده گیت آشنا شدید. این ابزار میتواند جایگاه بسیار برجستهای بیابد. به عنوان نمونه میتوانید سرویسها را طوری پیکربندی کنید تا با گیت کار کنند و به صورت خودکار کد خود را توزیع و تست کنید.
اکنون که میدانید گیت و گیتهاب چه هستند، زمان آن رسیده است که با تمرینهای منسجمی کار با آنها را بیاموزید. پس از اجرای این تمرینها قادر خواهید بود پروژههای خود را از طریق گیتهاب ساخته و مدیریت کنید و از قابلیتهای مقدماتی آن بهره بگیرید.
نکته: ما به این دلیل گیتهاب را به عنوان سرویس میزبانی خود انتخاب کردهایم که بیشترین استفاده را در دنیا دارد. البته جای نگرانی نیست چون سرویسهای دیگر نیز رویه مشابهی دارند.
به خاطر داشته باشید که باید همه دستورهای مقدماتی Shell را بدانید، چون در غیر این صورت بخشهایی از این مقاله برای شما سردرگمکننده خواهند بود.
نخستین تمرین زیاد پیچیده نیست و به دو بخش تقسیم میشود. نصب گیت و ایجاد حساب گیتهاب
برای ایجاد حساب گیتهاب باید به صفحه اصلی وبسایت گیتهاب (+) بروید و فرم ثبت نام را پر کنید.
این تنها کار لازم است و شما اینک رسماً یکی از اعضای گیتهاب هستید.
اکنون باید ابزارهای گیت را روی رایانه خود نصب کنیم. نرمافزارهای گیت مختلفی وجود دارند؛ اما بهتر است کار خود را ابزارهای مقدماتی شروع کنیم. ما از خط فرمان برای ارتباط با گیتهاب استفاده میکنیم. زمانی که با خط فرمان احساس راحتی بیشتری کردید، میتوانید نرمافزار گیت را به همراه یک اینترفیس کاربری دانلود کنید.
ابتدا پکیجهای خود را بهروزرسانی کنید:
sudo apt update
سپس گیت را با دستور apt-get نصب کنید:
sudo apt-get install git
در نهایت بررسی کنید که گیت به درستی نصب شده است یا نه:
git –version
ابتدا آخرین نسخه گیت را برای مک (+) دانلود کنید. سپس دستورالعملهایی را که روی صفحه نمایش مییابد پیگیری کنید. در نهایت یک ترمینال باز کنید و تأیید کنید که گیت به طرز صحیحی نصب شده است:
git –version
ابتدا نسخه نصبی گیت را از این لینک (+) برای ویندوز دانلود کنید. سپس با پیگیری دستورالعملهای نمایش یافته روی صفحه آن را نصب کنید. در نهایت یک ترمینال برای مثال پاورشل یا git bash را باز کرده و بررسی کنید که گیت به درستی نصب شده باشد:
git –version
آخرین گامی که برای نصب صحیح لازم است این است که ترمینال را با دستورهای زیر اجرا و اطلاعات خود را وارد کنید تا یک نام کاربری و ایمیل پیشفرض در زمان ذخیرهسازی کارهای خود داشته باشید:
git config --global user.name "Gaël Thomas" $ git config --global user.email example@mail.com
اکنون که آماده هستید، میتوانید به صفحه اصلی گیتهاب بازگردید و روی آیکون بعلاوه (+) در نوار منو کلیک کنید. زمانی که روی این دکمه کلیک کنید، یک منوی جدید با مدخل «New repository» ظاهر میشود. روی آن کلیک کنید.
در این مرحله صفحه ایجاد ریپازیتوری ظاهر خواهد شد. یک نام مناسب برای نخستین ریپازیتوری خود انتخاب کنید و پیش از کلیک کردن روی دکمه Create repository یک توضیح کوتاه برای آن وارد کنید.
نکته: بر اساس این چارچوب این راهنما فعلاً نیازی به ساخت فایل Read Me نداریم و آن را در ادامه ایجاد خواهیم کرد. بنابراین در حال حاضر میتوانید گزینه Initialize this repository with a README را انتخاب نشده باقی بگذارید.
بدین ترتیب ما موفق شدیم نخستین ریپازیتوری گیتهاب خود را ایجاد کنیم. اگر میخواهید همه ریپازیتوریهای خود را ببینید، باید روی تصویر پروفایل در نوار منو کلیک کنید و سپس گزینه Your repositories را انتخاب کنید.
اینک زمان آن رسیده است که نخستین تغییرهای خود را در ریپازیتوری ایجاد کنیم. شاید بهترین تغییر در این مرحله، ایجاد یک کاور مناسب برای آن است که شامل نوعی متن خوشامدگویی باشد.
نخستین مأموریت ما این است که یک کپی از ریپازیتوری ایجاد شده روی رایانه خود داشته باشیم. به این منظور باید ریپازیتوری را کلون کنیم. در صفحه ریپازیتوری آدرس HTTPS را دریافت کنید.
زمانی که آدرس ریپازیتوری را به دست آوردید، باید از ترمینال (از طریق دستورهای shell) برای جابجایی به مکانی که میخواهید کپی دایرکتوری را قرار دهید استفاده کنید. برای مثال میتوانید آن را به پوشه Documents انتقال دهید. زمانی که آماده بودید، دستور زیر را وارد کنید:
git clone [HTTPS ADDRESS]
این دستور یک کپی محلی از ریپازیتوری موجود در آدرس فوق ایجاد میکند.
اکنون این ریپازیتوری روی سیستم شما قرار دارد و باید با دستور زیر به مکان آن جابجا شوید:
cd [NAME OF REPOSITORY]
نکته: زمانی که یک ریپازیتوری را کلون میکنید، گیت یک ریپازیتوری روی رایانه شما ایجاد میکند. اگر دوست داشته باشید، میتوانید با رابط کاربری رایانه نیز به پروژه خود دسترسی داشته باشید.
اکنون میتوانید از طریق ترمینال یا رابط کاربری رایانه خود فایلی به نام «README.md» در پوشه پروژه ایجاد کنید. ما قصد نداریم در خصوص جزییات این مرحله به شما توضیح دهیم، چون موضوع خاصی وجود ندارد. کافی است پوشه را باز کنید و چنان که به طور معمول عمل میکنید، یک فایل در آن ایجاد کنید.
اگر میخواهید این کار را به روشی جالب انجام دهید، قالب ارائه شده در ادامه را در فایل README.md کپی کنید و اطلاعات را جایگزین نمایید تا یک خروجی شخصیسازیشده داشته باشید.
اینک که پروژه را اصلاحکردهاید باید آن را ذخیره کنید. این فرایند «کامیت» (Commit) کردن نام دارد. به این منظور باید به ترمینال بازگردید. اگر ترمینال را بستهاید باید به نشانی پوشه مراجعه کنید.
زمانی که میخواهید کارهای خود را ذخیره کنید، به چهار مرحله نیاز دارید. این مراحل به ترتیب status ،add ،commit و push نامیده میشوند. ما یک رویه استاندارد برای شما آماده کردهایم تا هر بار که میخواهید کارهایتان را ذخیره کنید مورد استفاده قرار دهید.
نکته: همه مراحل زیر باید درون پروژه اجرا شوند.
نخستین کاری که در زمان ذخیرهسازی کارهای خود باید انجام دهید، بررسی فایلهایی است که تغییر دادهاید. به این منظور میتوانید دستور زیر را وارد کید تا فهرستی از تغییرها ظاهر شود:
git status
به کمک فهرست تغییرها میتوانید همه فایلهایی را که میخواهید با دستور زیر آپلود کنید:
git add [FILENAME] [FILENAME] [...]
در این مورد قصد داریم فایل README.md را اضافه کنیم، زیرا مقصود ما ذخیرهسازی این فایل است.
git add README.md
نکته: اگر در این مرحله دوباره دستور git status را اجرا کنید، میبینید که این بار فایل RADME.md به رنگ سبز ظاهر میشود. این بدان معنی است که ما فایل را به درستی اضافه کردهایم.
اکنون که فایلهای منتخب خود را اضافه کردهایم، باید یک پیام بنویسیم و در آن کاری که انجام یافته را توضیح دهیم. این پیام بعدها در صورتی که بخواهیم سابقه تغییرها را بررسی کنیم مفید خواهد بود. مثالی از پیامی که میتوان نوشت به صورت زیر است:
git commit -m "Added README.md with good description in it."
بدین ترتیب به مرحله پایانی رسیدهایم، اینک میتوانیم کار خود را به صورت آنلاین منتشر کنیم. اگر دستور زیر را وارد کنید، همه تغییرهایی که اجرا کردهاید آنلاین میشوند و مستقیماً روی صفحه ریپازیتوری قابل مشاهده خواهند بود:
git push origin master
بدین ترتیب کار به پایان رسیده است. اگر به صفحه ریپازیتوری روی وبسایت گیتهاب بروید میتوانید فایل README.md را با پیشنمایش زیبایی مشاهده کنید.
شما به عنوان یک مبتدی در زمینه گیت باید با برخی دستورهای ضروری دیگر آن آشنا شوید. در ادامه فهرستی از دستورهایی را که در زمان کار روی پروژه مفید خواهند بود مشاهده میکنید.
نمایش سابقه کامیتها: با استفاده از دستور زیر میتوانید همه تغییرهایی را که روی پروژه اجرا شده است ملاحظه کنید:
git log
بازگردانی تغییرها: با استفاده از دستور زیر میتوانید تغییرهایی را که از زمان آخرین کامیت انجام یافتهاند، به حالت قبل بازگردانید.
git checkout.
بازگردانی تغییرات یک فایل: اگر میخواهید همه تغییرات یک فایل خاص را از زمان آخرین کامیت بازگردانید، میتوانید از دستور زیر استفاده کنید:
git checkout [FILENAME]
نمایش تغییرات فایل: برای نمایش تغییرهای یک فایل خاص از زمان آخرین کامیت از دستور زیر میتوان بهره گرفت:
git diff [FILENAME]
حذف فایلهای ناخواسته: برای حذف فایلهای ناخواسته (یعنی فایلهایی که کامیت نشدهاند) از پروژه میتوان از دستور زیر استفاده کرد:
git clean –dfx
افزودن همه فایلها: برای اضافه کردن همه فایلها و کامیت کردن آنها به صورت یکباره دستور زیر را اجرا کنید:
git commit -am [MESSAGE]
ب
منبع: فرادرس
امروزه، حجم دادههایی که افراد برای تحلیل مورد استفاده قرار میدهند افزایش قابل توجهی داشته است. همین امر، منجر به مشکلات و چالشهایی ضمن نوشتن و اجرای برنامههایی شده است که با حجم انبوهی از دادهها کار میکنند. یکی از این مشکلات، مساله اجرا نشدن برنامه در نرمافزار «متلب» (MATLAB) و نمایش خطای Out of Memory است. کاربران زیادی با این پرسش مواجه هستند که چگونه میتوان مشکل کمبود حافظه هنگام اجرای برنامه در متلب را حل کرد. دکتر «سید مصطفی کلامی هریس»، در پادکستی که در ادامه آمده، به این پرسش به طور مشروح پاسخ داده است. نسخه متنی این پادکست نیز در همین مطلب قرار دارد. البته، منبع اصلی همچنان فایل صوتی محسوب میشود.
ذخیره کردن این فایل صوتی: لینک دانلود
یکی از مشکلات رایجی که که افراد گزارش میکنند، پیرامون مسالهای است که در اجرای برنامههای خود در «متلب» (MATLAB) دارند. وقتی حجم دادههای مساله و در واقع، حجم مساله از یک اندازه بزرگتر میشود، دیگر برنامه اجرا نمیشود و پیام خطای «کمبود حافظه» (Out of Memory) به کاربر نمایش داده میشود. یعنی حافظه تمام شده است و به اندازه کافی جا ندارد. در اینجا، منظور از «حافظه» (Memory)، «رم» (RAM) است. یعنی، حافظهای که برنامهها در آن اجرا میشوند. بنابراین، اگر رم به اندازه کافی وجود نداشته باشد، طبیعتا گنجایش لازم وجود ندارد و برنامهها نمیتوانند اجرا شوند.
چند راهکار برای حل این مساله وجود دارد. البته ابتدا باید بررسی شود که واقعا به میزان خاصی از رم نیاز باشد. گاهی، برنامه درست نوشته نشده و محاسبات و دادههای اضافی ضمن اجرای آن لود میشوند. بعضا در این شرایط میتوان موضوع را در همین مرحله حل کرد. اما گاهی چنین موضوعی حل شده است؛ اما، مثلا یک کامپیوتر با هشت گیک رم موجود است ولی برنامه کاربر به بیست گیگ رم احتیاج دارد.
به دو روش میتوان این مساله را حل کرد. یکی اینکه از کامپیوتر دیگری استفاده شود که خب فرض میشود امکان تغییر و ارتقا سختافزار وجود ندارد. روش دیگر این است که «حافظه مجازی» (Virtual Memory) به سیستم اضافه شود. یعنی، بخشی از «درایو دیسک سخت» (Hard Disk Drive) به عنوان رم تعریف شود. این امکان، در بخش «System Properties» در کنترل پنل تعبیه شده است. در نسخههای متفاوت ویندوز، امکان دارد جای آن متفاوت باشد. معمولا میتوان آن را با کلیک راست روی «My Computer» و از System Properties، بخش Advance، در قسمت Performance پیدا کرد. با جستجوی عبارتهایی مانند «Add Virtual Memory» در گوگل نیز میتوان روش آن را پیدا کرد.
با این قابلیت، به عنوان مثال اگر پارتیشن هارد ۳۰ گیگ فضا خالی دارد، ۳۰ گیگ به رم میتوان اضافه کرد تا در واقع از بخشی از این هارد دیسک نیز به عنوان RAM استفاده کند. البته اگر هارد کامپیوتر فرد از نسخههای قدیمی باشد، سرعت آن پایین است و این موجب افت کیفیت اجرای برنامه میشود. اما اگر هارد از مدلهای جدید و SSD باشد، به خوبی میتواند اثرگذار باشد و سرعت همچون وقتی که از هاردهای کلاسیک استفاده میشود، خیلی کاهش پیدا نمیکند. البته، به هر حال استفاده از هارد دیسک به عنوان حافظه مجازی نمیتواند به خوبی رم باشد. این مورد را حتما باید در نظر داشت، ولی به هر حال مشکل را حل میکند. البته در شرایط بیان شده، کمی کارایی کاهش پیدا میکند ولی به هر حال میتوان با استفاده از کامپیوتر موجود، کار را انجام داد و برنامه را اجرا کرد. یعنی در واقع، گاهی ناگزیر باید این کار را انجام داد. یعنی، بخشی از هارد، یا یک یا چند پارتیشن را، به عنوان یک رم ثانویه و در واقع، یک رم مجازی (Virtual Memory) تخصیص داده و سایر کارها را خود سیستم عامل جلو میبرد.
البته این را نیز باید مد نظر داشت که بعد از انجام این تنظیمات، باید متلب را بست و دوباره باز کرد و گاهی حتی نیاز میشود کامپیوتر را Reset کرد. این موضوع، بستگی به «پیکربندی» (Configuration) سیستم کاربر دارد. برای حصول اطمینان از اینکه این تغییرات اعمال شده است، میتوان در Task Manager و با استفاده از کلیدهای ترکیبی Ctrl+Shift+Escape، میتوان آمارهای مربوط به سیستم را مشاهده کرد. در این بخش، میتوان میزان حافظه در دسترس (Available)، میزان حافظه مجازی (Virtual Memory) و حافظه فیزیکی (Physical Memory) را مشاهده کرد.
به هر حال، مساله Out of Memory نه تنها در متلب که در بقیه نرمافزارها نیز ممکن است به وقوع بپیوندد و آن را میتوان بدین شکل حل کرد. از آنجا که بسیاری از دانشجویان از متلب استفاده میکنند و این موضوع، مشکل شایعی در این نرمافزار است، راه حل آن را بیان کردم.
برای دانلود کردن و شنیدن دیگر پادکستهای دکتر سید مصطفی کلامی هریس در مجله فرادرس، روی این لینک [+] کلیک کنید.
منبع: فرادرس
در این نوشته میخواهیم یک ربات خزنده وب بسازیم تا روی صفحههای مختلف جستجو کرده و اطلاعاتی برای ما گردآوری کند. بدین منظور از یک فریمورک پایتون به نام Scrapy استفاده خواهیم کرد.
بر اساس تعریف ویکیپدیا، Scrapy که skray-pee تلفظ میشود یک فریمورک خزش وب اوپنسورس و رایگان است که به زبان پایتون نوشته شده است. این فریمورک در ابتدا برای وب اسکرپینگ طراحی شده بود و اکنون میتوان از آن برای استخراج دادهها با استفاده از API-ها و یا به عنوان یک خزنده وب عمومی استفاده کرد. این فریمورک در حال حاضر از سوی شرکت Scrapinghub نگهداری میشود که ارائهدهنده خدمات برنامهنویسی وب اسکرپینگ است.
Scrapy ایده پروژهای را مطرح کرد که چندین خزنده یا عنکبوت در یک پروژه منفرد داشته باشد. این مفهوم به طور خاص در مواردی مفید است که مشغول نوشتن چندین خزنده برای بخشهای مختلف یا زیردامنههای متفاوت یک سایت باشیم. بنابراین در ابتدا یک پروژه میسازیم:
با اجرای دستور زیر یک پروژه با نام olx ایجاد و اطلاعاتی را که برای مراحل بعدی کار مفید هستند ارائه میشوند.
ابتدا به پوشه جدیداً ایجاد شده میرویم و سپس دستوری برای تولید نخستین عنکبوت با نام دامنه و سایتی که باید خزیده شود، وارد میکنیم:
ما کد عنکبوت نخست خود را با نام electronics ساختیم، زیرا قصد داریم به بخش electronics در سایت OLX دسترسی پیدا کنیم. شما میتوانید نام عنکبوت خود را بر اساس نیازهای خود تعیین کنید.
ساختار پروژه نهایی چیزی مانند تصویر زیر خواهد بود:
همان طور که میبینید یک پوشه مستقل برای هر عنکبوت وجود دارد. شما میتوانید چند عنکبوت را به یک پروژه منفرد اضافه کنید. اگر فایل عنکبوت electronics.py را باز کنیم با چیزی مانند زیر مواجه میشویم:
چنان که مشاهده میکنید، ElectronicsSpider یک زیرکلاس از scrapy.Spider است. مشخصه name در واقع نام عنکبوت است که در دستور تولید عنکبوت تعیین شده است. این نام در زمانی که خزنده، خود را اجرا میکند به کار میآید. مشخصه allowed_domains تعیین میکند که کدام دامنهها در دسترس این خزنده هستند و start_urls جایی است که URL-های ابتدایی در آنجا نگهداری میشوند. این URL-های ابتدایی در زمان آغاز به کار عنکبوت مورد نیاز هستند. علاوه بر ساختار فایل، این یک قابلیت خوب برای ایجاد کرانهایی برای خزنده است.
متد parse چنان که از نامش برمیآید، محتوای صفحهای را که مورد دسترسی قرار داده است تحلیل خواهد کرد. ما میخواهیم خزندهای بنویسیم که به چندین صفحه برود و به این منظور باید برخی تغییرات ایجاد کنیم.
برای این که خزنده به چندین صفحه سر بزند، به جای scrapy.Spider یک زیرکلاس از آن ایجاد میکنیم. این کلاس موجب میشود که خزش روی صفحههای چندگانه آسانتر باشد. شما میتوانید با کد تولید شده هر کاری که دوست دارید انجام دهید، اما باید مواظب باشید که دوباره به صفحههای قبلی بازنگردید.
گام بعدی این است که متغیرهای قاعده خود را تنظیم کنید. در اینجا قواعد ناوبری وبسایت را بررسی میکنیم. LinkExtractor در واقع پارامترهایی برای رسم کرانها میگیرد. ما در این مثال از پارامتر restrict_css برای تعیین کلاسی جهت صفحه بعدی استفاده میکنیم. اگر به این صفحه (+) مراجعه کنید، چیزی مانند تصویر زیر را مشاهده خواهید کرد:
pageNextPrev کلاسی است که برای واکشی لینکها صفحههای بعدی استفاده میشود. پارامتر call_back مشخصی میکند که کدام متد برای دسترسی به عناصر استفاده میشود. این متد را در ادامه بررسی میکنیم.
به خاطر داشته باشید که باید نام متد را از ()parse به ()parse_item با هر چیزی که دوست دارید تغییر دهید تا از override شدن کلاس مبنا جلوگیری شود. در غیر این صورت قاعده شما کار نخواهد کرد حتی اگر مقدار follow=True تنظیم کنید.
تا به اینجا همه چیز به خوبی پیش رفته است. در ادامه خزندهای را که تا به اینجا ساختهایم تست میکنیم. در دایرکتوری پروژه به ترمینال بروید و دستور زیر را وارد کنید:
پارامتر سوم در واقع نام عنکبوتی است که قبلاً در مشخصه name کلاس ElectronicsSpiders تعیین کردهایم. در ترمینال اطلاعات مفید زیادی مییابید که برای دیباگ کردن خزنده مفید هستند. در صورتی که نخواهید اطلاعات دیباگ کردن را ببینید، میتوانید گزینه debugger را غیرفعال کنید. دستور مشابهی با سوئیچ –nolog وجود دارد:
اگر این دستور را در حال حاضر اجرا کنید، خروجی چیزی مانند زیر خواهد بود:
از آنجا که مقدار follow=True را تنظیم کردهایم، خزنده قاعده صفحه بعد را بررسی میکند و به ناوبری خود ادامه میدهد، مگر این که به صفحهای برخورد کند که قاعده در مورد آن صدق نمیکند که معمولاً صفحه آخر لیست است.
اینک تصور کنید بخواهیم منطق مشابهی را با چیزهایی که در این صفحه (+) اشاره شدهاند بنویسیم، ابتدا باید کدی بنویسیم که روی چندین پردازنده کار کند. همچنین باید کدی بنویسیم که نه تنها به صفحه بعد برود، بلکه اسکریپت را از طریق عدم دسترسی به URL های ناخواسته، در داخل کرانهای تعریف شده نگه دارد. Scrapy همه این وظایف را از دوش ما بر میدارد و کاری میکند که صرفاً روی منطق متمرکز شویم، یعنی خزندهای برای استخراج اطلاعات بنویسیم. اینک قصد داریم کدی بنویسیم که لینکهای آیتم منفرد مانند صفحههای فهرستبندی را واکشی کند بدین ترتیب کدی را که در متد parse_item داشتیم تغییر میدهیم:
در این کد ما لینکها را با استفاده از متد css. پاسخ واکشی میکنیم. چنان که گفتیم میتوان از xpath نیز استفاده کرد و بستگی به نظر شما دارد.. در این حالت همه چیز کاملاً ساده خواهد بود:
لینک دیگر کلاسی به نام detailsLink دارد. اگر تنها از (‘response.css(‘.detailsLink استفاده کنیم، در این صورت لینکهای تکراری از یک مدخل منفرد گردآوری میشوند، زیرا لینکها در تگهای img و h3 تکرار شدهاند. همچنین به کلاس والد large اشاره کردهایم تا لینکهای یکتا دریافت کنیم. ما از (attr(href:: برای استخراج بخش href خود لینک استفاده میکنیم. سپس از متد ()extract استفاده میکنیم.
دلیل استفاده از این متد آن است که css. و xpath. شیء SelectorList را بازگشت میدهند و ()extract به بازگرداندن DOM واقعی برای پردازش بیشتر کمک میکند. در نهایت لینکها را در scrapy.Request با یک callback به صورت کامل yield میکنیم. ما کد داخلی Scrapy را بررسی نکردهایم، اما احتمالاً از yield به جای return استفاده میکند، زیرا میتوانید چندین آیتم را return کنید. از آنجا که خزنده باید مراقب لینکهای چندگانه همراه با هم نیز باشد، در این صورت yield بهترین انتخاب خواهد بود.
متد parse_detail_page چنان که از نامش هویدا است، اطلاعات منفرد را از صفحه جزییات تحلیل میکند. بنابراین اتفاقی که در عمل میافتد این است که:
از آنجا که تنها پیمایش دوسطحی وجود دارد، قادر شدیم به کمک دو متد به پایینترین سطح برسیم. اگر قصد داشتیم شروع به خزش از صفحه اصلی وبسایت OLX بکنیم، باید سه متد مینوشتیم که دو مورد برای واکشی دستهبندیهای فرعی و مداخل آنها و متد آخر برای تحلیل اطلاعات واقعی بود.
در نهایت قصد داریم اطلاعات واقعی را تحلیل کنیم که روی یکی از مدخلها مانند این (+) در دسترس است.
تحلیل اطلاعات این صفحه کار دشواری نیست، اما این کاری است که باید روی اطلاعات ذخیرهشده صورت بگیرد. ما باید model را برای دادههای خود تعریف کنیم. این بدان معنی است باید به Scrapy بگوییم چه اطلاعاتی را میخواهیم برای استفادههای بعدی ذخیره کنیم. در ادامه فایل item.py را ویرایش میکنیم که قبلاً از سوی Scrapy ایجاد شده است:
OlxItem کلاسی است که در آن فیلدهای مورد نیاز برای نگهداری اطلاعات را تنظیم خواهیم کرد. ما قصد داریم سه فیلد برای کلاس مدل خود تعریف کنیم.
در این فیلدها عنوان مطلب، قیمت و خود URL را ذخیره میکنیم. در این مرحله به فایل کلاس خزنده بازمیگردیم و parse_detail_page را ویرایش میکنیم. اکنون یک متد برای آغاز نوشتن کد، یکی برای تست از طریق اجرای کل خزنده و دیگری برای مشاهده درست بودن مسیر است، اما ابزار جالب دیگری نیز وجود دارد که از سوی Scrapy عرضه شده است.
Shell یا پوسته Scrapy (+) یک ابزار خط فرمان است که فرصت تست کد تحلیلشده را بدون اجرای کلی خزنده در اختیار ما قرار میدهد. برخلاف خزنده که به همه لینکها سر میزند، شل Scrapy اقدام به ذخیرهسازی DOM یک صفحه منفرد برای استخراج دادهها میکند:
Adnans-MBP:olx AdnanAhmad$ scrapy shell https://www.olx.com.pk/item/asus-eee-pc-atom-dual-core-4cpus-beautiful-laptops-fresh-stock-IDUVo6B.html#4001329891
اکنون میتوان به سادگی کد را بدون مراجعه چندباره به همان URL تست کرد. بدین ترتیب عنوان صفحه را با کد زیر واکشی کردهایم:
In [8]: response.css('h1::text').extract()[0].strip() Out[8]: u"Asus Eee PC Atom Dual-Core 4CPU's Beautiful Laptops fresh Stock"
آن response.css آشنا را اینجا هم میتوانید مشاهده کنید. از آنجا که کل DOM موجود است میتوان هر کاری با آن انجام داد. برای نمونه آن را میتوان به صورت زیر واکشی کرد:
In [11]: response.css('.pricelabel > strong::text').extract()[0] Out[11]: u'Rs 10,500'
نیازی به انجام هیچ کاری برای واکشی url نیست، زیرا response.url اقدام به بازگشت دادن URL-ی میکند که هم اینک مورد دسترسی قرار گرفته است.
اکنون که همه کد را بررسی کردیم، نوبت آن رسیده است که parse_detail_page را مورد استفاده قرار دهیم:
وهله OlxItem پس از تحلیل کردن اطلاعات لازم ایجاد میشود و مشخصهها تعیین میشوند. اینک که نوبت اجرای خزنده و ذخیرهسازی اطلاعات رسیده است، کمی تغییر در دستور باید ایجاد کرد:
scrapy crawl electronics -o data.csv -t csv
ما نام فایل و قالببندی فایل را برای ذخیرهسازی دادهها ارسال میکنیم. زمانی که دستور فوق اجرا شود فایل CSV برای شما میسازد. چنان که میبینید روند سادهای است و برخلاف خزندهای که خود میباید مینوشتیم، در اینجا کافی است رویه مورد نیاز برای ذخیرهسازی دادهها را بنویسیم.
اما زیاد عجله نکنید! کار به همین جا ختم نمیشود. شما میتوانید حتی دادهها را در قالب JSON نیز ذخیره کنید، تنها کاری که به این منظور لازم است ارسال مقدار json با سوئیچ t- است.
Scrapy قابلیتهای دیگری نیز در اختیار ما قرار میدهد. برای نمونه میتوان یک نام فایل ثابت ارسال کرد که در سناریوهای دنیای واقعی هیچ معنایی ندارد. چرا باید برنامهای نوشت که نام فایل ثابتی تولید کند؟ یکی از موارد استفاده آن این است که باید فایل settings.py را اصلاح و این دو مدخل را اضافه کنید:
FEED_URI = 'data/%(name)s/%(time)s.json' FEED_FORMAT = 'json'
در ادامه الگوی فایلی که ایجاد کردهایم را ارائه میکنیم. %(name)% نام خود خزنده است، time زمان را نشان میدهد. اکنون زمانی که دستور زیر را اجرا کنیم:
scrapy crawl --nolog electronics
و یا دستور زیر را اجرا کنیم:
scrapy crawl electronics
یک فایل JSON در پوشه data مانند زیر ایجاد میشود: