爬虫入门

最近在由于项目的需要,需要从一个网站上爬取一些数据,量不是特别大,于是就自己动手写了一个小爬虫。爬虫虽小,五脏具全,好歹是将整个过程体验了一下。下面是整个爬虫的开发过程。

开发准备

对于写一个简单的爬虫来说,需要准备一些基础知识。实际来说,就是简单的获取网页的方法以及如何解析整个网页。在这篇文章中我们使用 php 来完成整个爬虫的开发。需要用到 php_curl 模块和 php 的多线程(虽然这不是 php 所擅长的)以及正则的基本知识。

获取网页

这个是很基础的部分,主要是利用 php_curl 去获取整个页面的内容

// $url 是最初始的 url,爬虫从这里开始
$content = cls_curl::get($url);

当然,整个方法被我封装过了,具体的 php_curl 的使用方法,见这里

获取目标 url

为了让爬虫自动去爬取我所需要的内容。我得从网页中获取到目标网页的 url,那么就需要从初始网页中不断的去爬取 目标内容:

preg_match_all('#href=\"/shop/[0-9]*?\"#', $content, $out);

在整个代码中,大家看到了一些很奇怪的符号,这些就是正则表达式,爬虫并不是非得使用正则表达式,但是正则表达式匹配的饿效率却不是其他的方法可以比的。大家不要被这些符号吓到,精通正则表达式当然不是一件简单的事情,但是初步的了解,简单的使用还是不难的。如果想详细的了解,这里有一篇不错的教程。但是在这里,大家只需要了解以下的基本知识:

+ [0-9] 是匹配到任意一个数字
+ * 表示重复零次或更多次
+ ? 表示重复另次或者一次
+ *? 表示的是非贪婪模式,表示整个匹配的长度不会无限匹配下去。

所以大家就能了解的到我想匹配到的是一个以 'shop' 开始,后面接着数字的链接了。这样我就获取到了我的目标链接了。

获取目标内容

在获取到目标的网页 url 之后,我需要像之前那样获取到目标网页的内容,剩下的就是要获取目标网页的内容了:

preg_match_all('#<h1 class=\"shop-name\">\s(.*?)\s</h1>#s', $content, $shopname);

整个正则表达式也没什么新鲜的东西,也是将网页中的 shop-name 给爬取下来了,但是顺带将 h1a标签里面的内容也给爬下来了,但其实整个并不是我们想要的。我们需要的只是 shop-name。所以需要将一些额外的内容给过滤掉:

$name = preg_replace("/<(a.*?)>(.*?)<(\/a.*?)>/si","",$shopname[0][0]);
$name = preg_replace("/<(\/?h1.*?)>/si","",$name);

"/<(a.?)>(.?)<(/a.*?)>/si/" 是将整个 a 标签,包括标签里面的内容替换成"",

"/<(/?h1.*?)>/si" 则只是将 h1 标签去掉,把里面的内容留下。经过这两行代码后,我们所需要的内容其实就获取到了。没错,爬虫就是这么简单。

更高的爬取效率

上面的方法其实就已经是一个简单的爬虫了,但是网页的数量太多,如果一直安上面的方法来爬取的话,速度实在是太慢了。所以我们需要充分的将硬件利用起来,没错,就是利用多线程的方法同时使用多个爬虫去爬数据。这样就可以大大的提升爬虫的效率了。

$w = new worker();
$w->count = 1;
$w->is_once = true;

//利用后台线程来爬取数据,不能在 web 环境中运行
$count = 200000;        // 每个进程循环多少次
$w->on_worker_start = function($worker) use ($count) {
    //
};

$w->run();

可以通过线程来控制每个爬虫的爬取次数,这个 worker 工具并不是我写的,参考这里。好了,到这里,一个简单的爬虫基本就完成了,将数据存入数据库的部分我并没有写出来,那个根本就不需要专门说了。对于爬虫,也还是需要慢慢的探索。

微信公众号

© 2018 ray