Skip to content

Latest commit

 

History

History
441 lines (298 loc) · 12.8 KB

web-scraping-with-lwp.ar.pod

File metadata and controls

441 lines (298 loc) · 12.8 KB

NAME

تحليل المواقع باستخدام LWP

LANGUAGE

ar

ABSTRACT

سنتعلم كي� نقوم بتنزيل، تحليل و استخراج معلومات م�يدة من المواقع الالكترونية.

DESCRIPTION

سنتعلم كي� نقوم بتنزيل، تحليل و استخراج معلومات م�يدة من المواقع الالكترونية. انظر التعري� لمزيد من الت�صيل

TUTORIAL

ما هو تحليل مواقع الشبكة العنكبوتية

تحليل المواقع هو بشكل عام عبارة عن عملية تجميع معلومات مختل�ة من مواقع مختل�ة و من ثم ترتيبها و ح�ظها لاستخدامها �ي اغراض اخرى. مثلا المدونات و المواقع الاخبارية تقوم باستخراج معلومات مختل�ة من مواقع اخرى و من ثم تعرضها على موقعها بشكل موحد. مثال عربي : موقع شخصي يقوم بجلب الاخبار من موقع الجزيرة و العربية و يعرضها على ص�حته الخاصة.

ملاحظات قانونية

قبل ان تقوم بعملية تحليل لاي موقع تأكد من انك لا تخترق اي قوانين و ان الموقع �عليا يسمح بتنزيل معلوماته و استخدامه لاغراض اخرى.

  • اذا كان الموقع يقدم طريقة تواصل موحدة للمبرمجين Ù�الاÙ�ضل استخدامها

  • اقرا اتÙ�اقية الاستخدام

  • لا تقم باستخراج Ùˆ تجميع الايميلات Ùˆ معلومات الاتصال Ùˆ ما اشبه

  • احترم robots.txt

  • اÙ�صح عن هويتك بشكل واضح Ù�ÙŠ عمليات الاتصال.

  • تأكد من انك لا تقوم بعملية اغراق Ùˆ استهلاك لموارد الموقع الاخر

  • اقرا المقالات Ùˆ الكتب المؤلÙ�Ø© Ù�ÙŠ هذا الخصوص

بيئة العمل

لغرض الشرح لن�ترض اننا قمنا بعمل سير�ر شخصي على المن�ذ http://127.0.0.1 و توجد ص�حات مختل�ة مثلا ص�حة البداية و ص�حة خطأ عدم العثور على الص�حة المطلوبة404

جلب المعلومات

لجلب اي ص�حة ويب يمكن ان نستخدم مكتبة LWP::UserAgent لتقوم بعملية طلب و احضار الص�حة الالكترونية . ملاحظة : يمكن استخدام اي مكتبة اخرى مثلا: HTTP::Tiny, HTTP::Lite

�ي المثال ادناه سنقوم بتن�يذ طلب جلب باستخدام الامر GET

use LWP::UserAgent;

my $ua =
  LWP::UserAgent->new(agent => 'MyWebScaper/1.0 <http://example.com>');

my $response = $ua->get('http://127.0.0.1/');

if ($response->is_success) {
    say $response->decoded_content;
} else {
    die $response->status_line;
}

بعد تن�يذ هذا الكود �سنتحصل على نسخة من الص�حة التي طلبناها اذا تمت العملية بنجاح. او �ي حالة �شل عملية الاتصال و تحميل الص�حة سيرجع لنا الكود رسالة خطأ

لنقم بمحاولة تنزيل ص�حة غير موجودة على السير�ر:

use LWP::UserAgent;

my $ua =
  LWP::UserAgent->new(agent => 'MyWebScaper/1.0 <http://example.com>');

my $response = $ua->get('http://127.0.0.1/not_found');

if ($response->is_success) {
    say $response->decoded_content;
} else {
    die $response->status_line;
}

هنا الخطأ سيقع �ي جهة السير�ر و سيقوم السير�ر بارجاع رسالة الخطأ، و لكن ماذا لو �شلت عملية الاتصال بالسير�ر اساسا؟

use LWP::UserAgent;

my $ua =
  LWP::UserAgent->new(agent => 'MyWebScaper/1.0 <http://example.com>');

my $response = $ua->get('http://unknown.server');

if ($response->is_success) {
    say $response->decoded_content;
} else {
    die $response->status_line;
}

�ي هذه الحالة سنتحصل على الخطأ 500. و لكن يبدو ان السير�ر يعمل و لكن بشكل غير صحيح و هذا خلا� الواقع. لكي نتعر� على مصدر الخطا هل هو خارجي او داخلي تو�ر مكتبة LWP رسالة تنبيهية خاصة، انظر الكود التالية: use LWP::UserAgent;

my $ua =
  LWP::UserAgent->new(agent => 'MyWebScaper/1.0 <http://example.com>');

my $response = $ua->get('http://unknown.server');

my $client_warning = $response->headers->header('Client-Warning');

if ($client_warning && $client_warning eq 'Internal response') {
    die 'Internal error: ' . $response->status_line;
} else {
    die 'Server error: ' . $response->status_line;
}

الان يمكننا ان نتأكد من ان الخطأ جاء من طر�نا.

تمرين

قم بتنزيل ص�حة من السير�ر الا�تراضي http://127.0.0.1 و قم بطباعة حجمها بالبايتس

use LWP::UserAgent;

my $ua = LWP::UserAgent->new;

...

say ...

__TEST__
like($stdout, qr/183/, 'Should print correct size');

التحليل

الان تعلمنا كي� نقوم بتحميل الص�حات و جلبها و سنقوم الان بعملية تحليل او استخراج لبعض المعلومات. �ي الامثلة القادمة لن نقوم بالتعامل مع الاخطاء طلبا للاختصار و لكن �ي الاستخدام الحقيقي يجب علينا التعامل مع كل حالة خطأ ممكنة.

الص�حة الا�تراضية تبدو بهذا الشكل :

# no-run
<html>
    <head>
        <title>A sample webpage!</title>
    </head>
    <body>
        <h1></h1>
    </body>
</html>

طبعا هذه اكواد html و للتعامل معها سنحتاج الى محلل الى html بالاضا�ة الى ما يعر� بمنقي Xpath و CSS حسب الحاجة طبعا.

XPath استخدام

بداية سنقوم بمحاولة تحليل الص�حة باستخدام HTML::TreeBuilder::XPath اكس باث هو عبارة عن لغة XML استعلامية. اذا لم تكن لديك اي معلومات مسبقة عن الاكس باث يمكنك ان تطلع هذا الملخص السريع: # no-run descendant-or-self::* all elements

//h1
<h1> element

descendant-or-self::h1/span
<span> within <h1>

descendant-or-self::h1 | descendant-or-self::span
<h1> and span

descendant-or-self::h1/descendant::span
<span> with parent <h1>

descendant-or-self::h1/following-sibling::*[name() = 'span' and (position() = 1)]
<span> preceded by <div>

descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' class ')]
Elements of class "class"

descendant-or-self::div[contains(concat(' ', normalize-space(@class), ' '), ' class ')]
<div> of class "class"

descendant-or-self::*[@id = 'id']
Element with id "id"

descendant-or-self::div[@id = 'id']
<div> with id "id"

descendant-or-self::a[@attr]
<a> with attribute "attr"

�ي هذا المثال سنقوم باستخراج عنوان الص�حة :

use HTML::TreeBuilder::XPath;

my $html = <<'EOF';
<html>
    <head>
        <title>A sample webpage!</title>
    </head>
    <body>
        <h1>Perltuts.com rocks!</h1>
    </body>
</html>
EOF

my $tree = HTML::TreeBuilder::XPath->new;
$tree->ignore_unknown(0);
$tree->parse($html);
$tree->eof;

my @nodes = $tree->findnodes('//title');
say $nodes[0]->as_text;

تمرين

استخرج ثم اطبع المحتويات المدرجة تحت h1

use HTML::TreeBuilder::XPath;

my $html = <<'EOF';
<html>
    <head>
        <title>A sample webpage!</title>
    </head>
    <body>
        <h1>Perltuts.com rocks!</h1>
    </body>
</html>
EOF

my $tree = HTML::TreeBuilder::XPath->new;
$tree->ignore_unknown(0);
$tree->parse($html);
$tree->eof;

my @nodes = $tree->findnodes(...);
say $nodes[0]->as_text;
__TEST__
like($stdout, qr/Perltuts.com rocks!/, 'Should print correct h1 content');

CSS selectors استخدام

البعض من المبرمجين يعتبر CSS اكثر سهولة من الاكس باث. اذا كنت لا تعر� CSS �اليك هذا الملخص السريع:

# no-run
*
all elements

h1
<h1> element

h1 span
<span> within <h1>

h1, span
<h1> and span

h1 > span
<span> with parent <h1>

div + span
<span> preceded by <div>

.class
Elements of class "class"

div.class
<div> of class "class"

#id
Element with id "id"

div#id
<div> with id "id"

a[attr]
<a> with attribute "attr"

باستخدام HTML::Selector::XPath يمكننا ان نجعل من المكتبة السابقة منقي CSS ...

use HTML::TreeBuilder::XPath;
use HTML::Selector::XPath;

my $html = <<'EOF';
<html>
    <head>
        <title>A sample webpage!</title>
    </head>
    <body>
        <h1>Perltuts.com rocks!</h1>
    </body>
</html>
EOF

my $tree = HTML::TreeBuilder::XPath->new;
$tree->ignore_unknown(0);
$tree->parse($html);
$tree->eof;

my $xpath = HTML::Selector::XPath::selector_to_xpath('h1');
my @nodes = $tree->findnodes($xpath);
say $nodes[0]->as_text;

تمرين

�ي هذا التمرين اكمل الكود �ي الاس�ل ليقوم بعملية جلب ثم استخراج و طباعة لمحتويات h1 و ذلك باستخدام منقي CSS :

use LWP::UserAgent;
use HTML::TreeBuilder::XPath;
use HTML::Selector::XPath;

my $ua = LWP::UserAgent->new;

my $response = ...
my $html = ...

my $tree = ...

my $xpath = HTML::Selector::XPath::selector_to_xpath(...);
my @nodes = $tree->findnodes($xpath);
say $nodes[0]->as_text;
__TEST__
like($stdout, qr/Perltuts.com rocks!/, 'Should print correct h1 content');

متابعة الوصلات و اعادات التحويل

اعادة تحويل

ليس من الغريب ان تقوم بعض الص�حات باعادة تحويل الى ص�حات اخرى. من حسن الحظ ان LWP::UserAgent تقوم بدعم التحويل ا�تراضيا. يمكن التحكم بعدد التحولات التي ستتولاها المكتبة من خلال max_redirect �ي المثال ادناه ص�حة ريداركت التي سنقوم بطلبها ستقوم بعملية اعادة تحويل الى ص�حة الاندكس او ما يسمى بالصح�ة الا�تراضية:

use LWP::UserAgent;

my $ua =
  LWP::UserAgent->new(agent => 'MyWebScaper/1.0 <http://example.com>');

my $response = $ua->get('http://127.0.0.1/redirect');

say $response->decoded_content;

نلاحظ اننا لو قمنا باسناد قيمة ص�ر الى max_redirect �انه لن يتم تحويلنا الى الص�حة الا�تراضية

use LWP::UserAgent;

my $ua = LWP::UserAgent->new(
    agent        => 'MyWebScaper/1.0 <http://example.com>',
    max_redirect => 0
);

my $response = $ua->get('http://127.0.0.1/redirect');

say $response->decoded_content;

الوصلات

متابعة الوصلات و الروابط مهمة معتادة �ي تحليل ص�حات الويب. مرة اخرى باستخدام منقي CSS يمكننا الحصول على الـ a تاج الخاص بالروابط. لنجرب: use HTML::TreeBuilder::XPath; use HTML::Selector::XPath;

my $html = <<'EOF';
<html>
    <head>
        <title>A sample webpage!</title>
    </head>
    <body>
        <h1>Perltuts.com rocks!</h1>
        <a href="http://perltuts.com">perltuts.com</a>
    </body>
</html>
EOF

my $tree = HTML::TreeBuilder::XPath->new;
$tree->ignore_unknown(0);
$tree->parse($html);
$tree->eof;

my $xpath = HTML::Selector::XPath::selector_to_xpath('a');
my @nodes = $tree->findnodes($xpath);
my @attrs = $nodes[0]->getAttributes();
say $attrs[0]->getValue();

انظر ايضا

انظر هذه المكتبات لمزيد من الاليات المساعدة �ي عملية تحليل المواقع

AUTHOR

Viacheslav Tykhanovskyi, [email protected]

TRANSLATOR

Ali Yassen, [email protected]

LICENSE

CC BY-SA 3.0

POD ERRORS

Hey! The above document had some coding errors, which are explained below:

Around line 3:

Non-ASCII character seen before =encoding in 'تحليل'. Assuming CP1252