Heim >Backend-Entwicklung >PHP-Tutorial >Blog-Crawling-System

Blog-Crawling-System

WBOY
WBOYOriginal
2016-08-08 09:30:251058Durchsuche

Einführung

Ich hatte am Wochenende nichts zu tun und war gelangweilt, also habe ich ein Blog-Crawling-System mit PHP erstellt. Natürlich besuche ich Cnblogs (sehen Sie, ich mag den Blog-Park immer noch). Mein Crawling-Vergleich Einfach: Rufen Sie den Inhalt der Webseite ab, verwenden Sie dann den regulären Abgleich, um das zu erhalten, was Sie möchten, und speichern Sie dann die Datenbank. Natürlich werden Sie im eigentlichen Prozess auf einige Probleme stoßen. Ich habe vorher darüber nachgedacht und möchte, dass es erweiterbar ist. Wenn ich in Zukunft csdn, 51cto, Sina-Blog und andere Inhalte hinzufügen möchte, kann es problemlos erweitert werden.

Diese Dinge können geschnappt werden?

Zunächst möchte ich etwas sagen. Nicht alles, was Sie auf der Webseite sehen, kann nicht gecrawlt werden, wie zum Beispiel das Folgende

Darunter die Anzahl der Lesungen, Kommentare, Empfehlungen, Einwände, Kommentare ... Diese werden dynamisch durch den Aufruf von Ajax durch js abgerufen, sodass sie tatsächlich nicht in einem Satz geöffnet werden können Klicken Sie mit der rechten Maustaste, um den Quellcode anzuzeigen. Wenn Sie den mit Ajax gefüllten Inhalt crawlen möchten, kann dies zu Problemen führen Ich habe zuvor einen Artikel gesehen. Laden Sie zuerst die Webseite über den Browser und filtern Sie dann das gesamte DOM (wie im Artikel erwähnt, ist es natürlich auch möglich, diese JS-Anfragen zu verbinden, aber das wird es). wahrscheinlich problematischer sein.

Ideen zum Krabbeln

Lassen Sie uns zunächst über die Kriechtiefe sprechen

Beginnen Sie zum Beispiel mit dem Crawlen von Link a. Wenn die Tiefe 1 ist, holen Sie sich einfach den Inhalt des aktuellen Links. Wenn die Tiefe 2 ist, passen Sie den Link gemäß den angegebenen Regeln an den Inhalt des Links an a. Der übereinstimmende Link wird ebenfalls mit einer Tiefe von 1 verarbeitet, und so weiter. Tiefe ist die Tiefe und Ebene des Links. Nur so kann der Crawler „kriechen“.

Wenn Sie einen Link zum Crawlen bestimmter Inhalte verwenden, sind die Dinge, die Sie crawlen können, natürlich sehr begrenzt, oder Sie sterben möglicherweise vor dem Crawlen (die nachfolgenden Ebenen stimmen nicht mit dem Inhalt überein). Sie können also beim Crawlen mehrere Starts festlegen Links beim Abrufen. Natürlich ist es wahrscheinlich, dass Sie beim Crawlen auf viele doppelte Links stoßen. Daher müssen Sie die gecrawlten Links markieren, um zu verhindern, dass derselbe Inhalt wiederholt erfasst wird, was zu Redundanz führt. Es gibt mehrere Variablen zum Zwischenspeichern dieser Informationen. Das Format ist wie folgt:

Erstens handelt es sich um ein Hash-Array, der Schlüsselwert ist der MD5-Wert der URL, der Status ist 0, ein eindeutiges URL-Array wird in der folgenden Form verwaltet

<span>Array</span><span>
(
    [bc790cda87745fa78a2ebeffd8b48145] </span>=> 0<span>
    [9868e03f81179419d5b74b5ee709cdc2] </span>=> 0<span>
    [4a9506d20915a511a561be80986544be] </span>=> 0<span>
    [818bcdd76aaa0d41ca88491812559585] </span>=> 0<span>
    [9433c3f38fca129e46372282f1569757] </span>=> 0<span>
    [f005698a0706284d4308f7b9cf2a9d35] </span>=> 0<span>
    [e463afcf13948f0a36bf68b30d2e9091] </span>=> 0<span>
    [23ce4775bd2ce9c75379890e84fadd8e] </span>=> 0
    ......<span>
)</span>

Das zweite ist das abzurufende URL-Array. Hier kann ich auch alle Links in das Array abrufen und dann das Array durchlaufen, um den Inhalt zu erhalten Die maximale Tiefe aller Inhalte minus 1 wurde zweimal abgerufen. Hier können Sie den Inhalt direkt abrufen, wenn Sie den Inhalt der nächsten Ebene abrufen, und dann den Status im obigen Array auf 1 (bereits erhalten) ändern, was die Effizienz verbessern kann. Schauen Sie sich zunächst den Inhalt des Arrays an, das den Link speichert:

<span>Array</span><span>
(
    [</span>0] => <span>Array</span><span>
        (
            [</span>0] => http:<span>//</span><span>zzk.cnblogs.com/s?t=b&w=php&p=1</span>
<span>        )
    [</span>1] => <span>Array</span><span>
        (
            [</span>0] => http:<span>//</span><span>www.cnblogs.com/baochuan/archive/2012/03/12/2391135.html</span>
            [1] => http:<span>//</span><span>www.cnblogs.com/ohmygirl/p/internal-variable-1.html</span>
            [2] => http:<span>//</span><span>www.cnblogs.com/zuoxiaolong/p/java1.html</span>
                ......<span>
        )

    [</span>2] => <span>Array</span><span>
        (
            [</span>0] => http:<span>//</span><span>www.cnblogs.com/ohmygirl/category/623392.html</span>
            [1] => http:<span>//</span><span>www.cnblogs.com/ohmygirl/category/619019.html</span>
            [2] => http:<span>//</span><span>www.cnblogs.com/ohmygirl/category/619020.html</span>
                ......<span>
        )

)</span>
Schließlich werden alle Links in einem Array zusammengefasst und zurückgegeben, und das Programm führt eine Schleife aus, um den Inhalt der Verbindung abzurufen. Genauso wie die obige Erfassungsebene 2 ist, wurde der Linkinhalt der Ebene 0 erfasst und nur zum Abrufen der Links der Ebene 1 verwendet. Der gesamte Linkinhalt der Ebene 1 wurde ebenfalls erfasst und wird nur dazu verwendet Speichern Sie die Links auf Ebene 2. Wenn der Inhalt tatsächlich abgerufen wird, wird der obige Inhalt erneut abgerufen und der Status im obigen Hash-Array wird nicht verwendet. . . (Zu optimieren).

Es gibt auch eine regelmäßige Regel für die Beschaffung von Artikeln im Blogpark. Durch die Analyse des Inhalts von Artikeln im Blogpark wurde festgestellt, dass der Titel und der Textkörper des Artikels grundsätzlich sehr regelmäßig abgerufen werden können

Der Titel und der Titel-HTML-Code haben das unten gezeigte Format. Sie können problemlos mit dem folgenden regulären Ausdruck abgleichen.

<span>#</span><span><a\s*?id=\"cb_post_title_url\"[^>]*?>(.*?)<\/a>#is</span>

Der Haupttext, der Haupttextteil, kann leicht über die Balance-Gruppe regulärer Ausdrücke mit erweiterten Funktionen abgerufen werden. Nach langer Arbeit stellte ich jedoch fest, dass PHP die Balance-Gruppe anscheinend nicht sehr gut unterstützt Deshalb habe ich die Bilanzgruppe aufgegeben und hinzugefügt. Im HTML-Quellcode wurde festgestellt, dass der Inhalt des Artikelkörpers durch die folgenden regulären Regeln leicht abgeglichen werden kann. Jeder Artikel hat grundsätzlich den Inhalt im Bild unten

<span>#</span><span>(<div\s*?id=\"cnblogs_post_body\"[^>]*?>.*)<div\s*id=\"blog_post_info_block\">#is</span>
Start:

Ende:

  博客的发布时间也是可以获取到的,但有些文章在获取发布时间的时候可能会找不到,这个就不列在这里了,有了这些东西就可以爬取内容了。

开始爬取

  开始爬取内容了,最初我设置的爬取深度是2级,初始页面是博客园首页,发现爬取不了多少内容,后来发现博客园首页有个页码导航

  就试图拼接成页码格式http://www.cnblogs.com/#p2,循环200次,以每页为起始页面,深度为2去抓取。但我高兴的太早了,开了几个进程跑了好久程序,抓了几十万条,后来发现完全在重复,都是从第一页中抓取的,因为博客园首页点击导航的时候(除了第一页),都是ajax请求获取到的。。。。看来博客园还是考虑到这个问题,因为大多数人都是只打开首页,不会去点击后面的内容(我可能偶尔会去点击下一页),所以为了在防止初级抓取者去抓取和性能发面做权衡,将第一页设置为静态网页的方式,缓存有效期是几分钟(或者是根据跟新频率,当更新多少篇的时候去更新缓存,或者两者的结合),这也是为什么有时候发布的文章,过一会儿才会显示出来的原因(我猜的^_^)。

  难道不能一次性抓取很多内容吗?后来我发现这个地方使用的全部是静态网页

     从找找看这个地方获取到的内容都是静态的,包括最下面的导航链接中的所有页面都是静态的,而且,这个搜索右边还有筛选条件,可以更好的提高抓取的质量。好了有了这个入口,就可以获取到好多高质量的文章了,下面是循环抓取100页的代码

<span>for</span>(<span>$i</span>=1;<span>$i</span><=100;<span>$i</span>++<span>){
            </span><span>echo</span> "PAGE{<span>$i</span>}*************************[begin]***************************\r"<span>;
            </span><span>$spidercnblogs</span> = <span>new</span> C\Spidercnblogs("http://zzk.cnblogs.com/s?t=b&w=php&p={$i}"<span>);
            </span><span>$urls</span> = <span>$spidercnblogs</span>-><span>spiderUrls();
            </span><span>die</span><span>();
            </span><span>foreach</span> (<span>$urls</span> <span>as</span> <span>$key</span> => <span>$value</span><span>) {
                </span><span>$cnblogs</span>->grap(<span>$value</span><span>);
                </span><span>$cnblogs</span>-><span>save();
            }
        }</span>

  至此,就可以去抓去自己喜欢的东西了,抓取速度不是很快,我在一台普通pc上面开了10个进程,抓了好几个小时,才获取到了40多万条数据,好了看看抓取到的内容稍微优化之后的显示效果,这里面加上了博客园的基础css代码,可以看出效果和

抓取到的内容稍作修改:

原始内容

 

 

 再看下文件目录结构,也是用上篇的自制目录生成工具生成的:

 +myBlogs-master
    +controller
        |_Blog.php
        |_Blogcnblogs.php
        |_Spider.php
        |_Spidercnblogs.php
    +core
        |_Autoload.php
    +interface
        |_Blog.php
    +lib
        |_Mysql.php
    +model
        |_Blog.php
    |_App.php

 效果还是很不错的,这里再猜下推酷这种专门爬取的网站的工作方式,一个常驻进程,隔一段时间去获取一次内容(比如说首页),如果有新鲜的内容入库,没有的话放弃这次获取的内容,等待下次获取,当时间很小的时候就可以一篇不漏的抓取的”新鲜“的内容。

这是github地址:

github——myBlogs

  本文版权归作者iforever(luluyrt@163.com)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

以上就介绍了博客爬取系统,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn