Email: info@developit.ir

ساخت یک هکر خبر خوان با استفاده از کلاس readability!

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

به عنوان مثال سایتی با موضوع پرورش هویج! تصمیم داره از مراجع مختلف اطلاعاتی در این زمینه جمع آوری و داخل سایت خودش نمایش بده.

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

من تصمیم دارم RSS یک سایت رو به این کلاس معرفی و در انتها آخرین محتوای ارسال شده اون سایت رو دریافت کنم.

توجه داشته باشین در RSS ها معمولا خلاصه و لینکی از مطلب وجود داره پس برای پیاده سازی باید مراحل زیرُ انجام بدیم:

1- تعریف RSS feed و خواندن محتوای آن
2- رجوع به هر لینک و خواندن محتوای صفحه
3- تحلیل صفحه و دریافت محتوای آن

خیلی ساده برای مرحله ی اول یک آرایه شامل لیستی از RSS های مورد نظرمون ایجاد میکنیم:

$rss = ['http://apps.shareholder.com/rss/rss.aspx?channels=632&companyid=YHOO&sh_auth=2296425907%2E0%2E0%2E42547%2E8297a590874dfcbc24ab8971766be6ad'];

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

foreach ($rss as $r)
{
    $rssContent = simplexml_load_file($r);
}

اطلاعات بیشتر در مورد simplexml_load_file

 مرحله اول تمام شد و ما محتوای RSS یا RSS ها رو به دست آوردیم. در مرحله دوم سعی میکنیم محتوای لینک مطالب رو دریافت کنیم.

در RSS داخل تگ یا بلاکی به نام item اطلاعاتی به شرح زیر وجود داره:

title: عنوان محتوا

description: توضیح مختصری در مورد محتوا

link: آدرس اینترنتی صفحه محتوا که اطلاعات کامل و مورد نظر ما در اونجا قرار داره

pubDate: تاریخ انتشار محتوا

کافیه به item ها برسیم و لینک ها رو دریافت کنیم

foreach ($rss as $r)
{
    $rssContent = simplexml_load_file($r);

    $count = count($rssContent->channel->item) - 1;
    for($i=0;$i<=$count;$i++)
    {
        $item = $rssContent->channel->item[$i];
        $link = (string)$item->link;
        $content = file_get_contents($link);
    }
}

مرحله دو هم انجام شد.

 

از اونجایی که مقدار content سورس کامل صفحه است و ما فقط نیاز به بخشی از این اطلاعات رو داریم در مرحله سوم از readability استفاده میکنیم

readability به طور پیشفرض سورس کامل رو دریافت میکنه و به طور خودکار دنبال اصلی ترین تگ HTML میگرده و اون بخش رو به ما میده. منظور از اصلی ترین تگ HTML دقیقا همون اطلاعاتی هست که ما دنبالش میگردیم اما مشکل اینجاست که فقط بین تگ های p جستجو میکنه و اگر داخل یک سایت مطلب یا محتوای اصلی داخل تگی به جز p مثلا div,section و... باشه درست کار نمیکنه.

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

من این کلاس رو تغییر دادم و میتونید اون رو در پیوست این مطلب مشاهده کنید اما به طور خلاصه:

یک 

public $element = 'p';

تعریف کردم با مقدار پیشفرض p که یعنی اگر تکی رو معرفی نکردم همون تگ p رو پیدا کن

در construct پارامتر سومی قرار دادم به نام element تا بتونم هنگام ایجاد یک شی از این کلاس element مورد نظر خودمم ارسال کنم.

  

function __construct($source, $input_char = "utf-8", $element = 'p') {

 داخل construct هم گفتم که:

if(!empty($element))
{
     $this->element = $element;
}

و در نهایت داخل متد getTopBox هم از element استفاده کردم:

$allParagraphs = $this->DOM->getElementsByTagName($this->element);

 حالا دیگه میتونیم به readability بگیم محتوای یک سایت دقیقا داخل چه تگی قرار داره.

میریم سراغ مرحله آخر یا سوم، یک شی از readability تعریف و با استفاده از متد getContent محتوای مورد نظرمونُ دریافت میکنیم

 

error_reporting(0);
require 'lib/readability.php';
$rss = ['http://apps.shareholder.com/rss/rss.aspx?channels=632&companyid=YHOO&sh_auth=2296425907%2E0%2E0%2E42547%2E8297a590874dfcbc24ab8971766be6ad'];

foreach ($rss as $r)
{
    $rssContent = simplexml_load_file($r);

    $count = count($rssContent->channel->item) - 1;
    for($i=0;$i<=$count;$i++)
    {
        $item = $rssContent->channel->item[$i];
        $link = (string)$item->link;
        $content = file_get_contents($link);
        $readability = new \Readability($content,'utf-8','div');
        $readability = @$readability->getContent();

        if(isset($readability['content']))
        {
            echo($readability['content']);
            echo '<hr>';
        }
    }
}

 من این اطلاعاتُ چاپ کردم اما شما میتونید اونها رو داخل دیتابیس ذخیره کنید.

اگر اطلاعات رو داخل دیتابیس ذخیره میکنید برای اینکه با هر بار اجرای کد لینک های تکراری دریافت نشه میتونید از یک فیلد با عنوانی مثل last_visited_link استفاده کنید و ابتدای شروع حلقه لینک اولین item رو داخلش ذخیره کنید، سپس بررسی کنید اگر اولین لینک خوانده شده از RSS با last_visited_link برابر بود حلقه ادامه پیدا نکنه.

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

 دریافت سورس کد این مقاله

 

 

این مطلب آخرین بار در تاریخ 19:18 - 1395/09/19 ویرایش شده است.
ارسال نظر
عضویت در خبرنامه
جهت اطلاع از آخرین فعالیت های من لطفا در خبرنامه عضو شوید