はじめに
週末は何もすることがなくて暇だったので、よくアクセスする php を使ってブログ クローリング システムを作りました。もちろんブログ パークから始めました (ほら、今でもブログ パークが好きです)。 Web ページのコンテンツを取得し、通常のマッチングを使用して必要なものを取得し、データベースを保存するのは比較的簡単です。もちろん、実際のプロセスではいくつかの問題が発生します。これを行う前にすでに考えており、将来 csdn、51cto、Sina blog などのコンテンツを追加したくなった場合に、簡単に拡張できるようにしたいと考えています。
それらのものは掴むことができますか?
まず最初に言っておきますが、これは単純なクロールです。次のようなものはクロールできないものもあります。
このうち、閲覧数、コメント数、推奨数、反対意見、コメント数…これらはjsがajaxを呼び出すことで動的に取得されるので、実際には一言でWebページを開いて右クリックするだけでは取得できません。クリックしてソース コードを表示します。この単純なクロールでは問題が発生する可能性があります。Ajax で埋められたコンテンツをクロールしたい場合は、別の方法を検討する必要があります。ブラウザが Web ページをロードした後、DOM 全体をフィルタリングします (もちろん、これらの JS リクエストを結合することも可能であると記事では述べられていますが、おそらくそうなるでしょう)。もっと面倒なことになる。
クロールのアイデア
まず、這う深さについて話しましょう
もちろん、リンクを使用して特定のコンテンツをクロールすると、クロールできるものが非常に限られたり、クロールする前に死んでしまう可能性があります(以降のレベルがコンテンツと一致しない)ので、クロール時に複数の開始リンクを設定できますいつでも。もちろん、クロール中に重複リンクが多数発生する可能性があるため、同じコンテンツが繰り返し取得されて冗長性が生じるのを防ぐために、クロールされたリンクにマークを付ける必要があります。この情報をキャッシュするにはいくつかの変数があり、形式は次のとおりですたとえば、リンク a からクロールを開始します。深さが 1 の場合は、現在のリンクのコンテンツを取得し、指定されたルールに従ってリンク a のコンテンツからリンクを照合します。一致したリンクも深さ 1 で処理します。深さはリンクの深さとレベルです。この方法でのみ、クローラーは「這う」ことができます。
まず、これはハッシュ配列であり、キー値は URL の md5 値、ステータスは 0、次の形式で一意の URL 配列を維持します
リーリー
記事の取得にも規則性があり、ブログパークの記事内容を分析すると、基本的には非常に規則的な方法で記事のタイトルと本文を取得できることが分かりました。2 番目は、取得する URL 配列です。これは、配列へのすべてのリンクを取得し、その配列をループしてコンテンツを取得することと同じです。ここでは、次のレベルのコンテンツを取得するときにコンテンツを直接取得し、上記の配列のステータスを 1 (取得済み) に変更することで効率が向上します。まず、リンクを保存する配列の内容を確認します:
リーリー最後に、すべてのリンクが配列に結合されて返され、プログラムがループして接続内のコンテンツを取得します。上記の取得レベルが 2 と同様に、レベル 0 のリンク コンテンツが取得されており、レベル 1 のリンクを取得するためにのみ使用されます。レベル 1 のリンク コンテンツもすべて取得されており、レベル 1 のリンク コンテンツのみを取得します。リンクをレベル 2 に保存します。実際にコンテンツを取得するときは、上記のコンテンツが再度取得され、上記のハッシュ配列のステータスは使用されません。 。 。 (最適化予定)。
タイトルとタイトルのHTMLコードはすべて以下に示す形式になっており、次の正規表現を使用して簡単に一致させることができますリーリー
テキスト、テキスト部分は正規表現の高度な機能のバランスグループを介して簡単に取得できますが、長い間作業した後、PHPがバランスグループをあまりよくサポートしていないようであることがわかったので、バランス グループを検索し、HTML ソース コードで見つけました。記事本文の内容も、次の規則に従って簡単に一致させることができます。各記事には、基本的に下の図の内容が含まれています開始:。 リーリー
終了:
博客的发布时间也是可以获取到的,但有些文章在获取发布时间的时候可能会找不到,这个就不列在这里了,有了这些东西就可以爬取内容了。
开始爬取
开始爬取内容了,最初我设置的爬取深度是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教程有兴趣的朋友有所帮助。