爬虫是我一直以来跃跃欲试的技术,现在的爬虫框架很多,比较流行的是基于python,nodejs,java,C#,PHP的的框架,其中又以基于python的爬虫流行最为广泛,还有的已经是一套傻瓜式的软件操作,如八爪鱼,火车头等软件。
今天我们首先尝试的是使用PHP实现一个爬虫程序,首先在不使用爬虫框架的基础上实践也是为了理解爬虫的原理,然后再利用PHP的lib,框架和扩展进行实践。
所有代码挂在我的github上。
1.PHP简单的爬虫–原型
爬虫的原理:
- 给定原始的url;
- 分析链接,根据设置的正则表达式获取链接中的内容;
- 有的会更新原始的url再进行分析链接,获取特定内容,周而复始。
- 将获取的内容保存在数据库中(mysql)或者本地文件中
下面是网上一个例子,我们列下来然后分析
从main
函数开始
1 |
|
2.使用crul lib
Curl是比较成熟的一个lib,异常处理、http header、POST之类都做得很好,重要的是PHP下操作MySQL进行入库操作比较省心。关于curl的说明具体可以查看PHP官方文档说明http://php.net/manual/zh/book.curl.php
不过在多线程Curl(Curl_multi)方面比较麻烦。
开启crul
针对winow系统:
php.in中修改(注释;去掉即可)
extension=php_curl.dll
php文件夹下的libeay32.dll, ssleay32.dll, libssh2.dll 还有 php/ext下的php_curl4个文件移入windows/system32
使用crul爬虫的步骤:
- 使用cURL函数的基本思想是先使用curl_init()初始化一个cURL会话;
- 接着你可以通过curl_setopt()设置你需要的全部选项;
- 然后使用curl_exec()来执行会话;
- 当执行完会话后使用curl_close()关闭会话。
例子
1 |
|
一个完整点的例子:
1 |
|
要对https支持,需要在_getUrlContent
函数中加入下面的设置:1
2
3
4
5curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
curl_setopt($ch, CURLOPT_USERPWD, "username:password");
curl_setopt($ch, CURLOPT_SSLVERSION,3);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
结果疑惑:
我们通过1和2部分得到的结果差异很大,第1部分能得到四千多条url数据,而第2部分却一直是45条数据。
还有我们获得url数据可能会有重复的,这部分处理在我的github上,对应demo2-01.php,或者demo2-02.php
3.file_get_contents/stream_get_contents与curl对比
3.1 file_get_contents/stream_get_contents对比
- stream_get_contents — 读取资源流到一个字符串
与 [file_get_contents()]一样,但是 stream_get_contents() 是对一个已经打开的资源流进行操作,并将其内容写入一个字符串返回
1 | $handle = fopen($url, "r"); |
- file_get_contents — 将整个文件读入一个字符串
1 | $content = file_get_contents($url, 1024 * 1024); |
【注】 如果要打开有特殊字符的 URL (比如说有空格),就需要使用进行 URL 编码。
3.2 file_get_contents/stream_get_contents与curl对比
php中file_get_contents与curl性能比较分析一文中有详细的对比分析,主要的对比现在列下来:
fopen /file_get_contents 每次请求都会重新做DNS查询,并不对 DNS信息进行缓存。但是CURL会自动对DNS信息进行缓存。对同一域名下的网页或者图片的请求只需要一次DNS查询。这大大减少了DNS查询的次数。所以CURL的性能比fopen /file_get_contents 好很多。
fopen /file_get_contents 在请求HTTP时,使用的是http_fopen_wrapper,不会keeplive。而curl却可以。这样在多次请求多个链接时,curl效率会好一些。
fopen / file_get_contents 函数会受到php.ini文件中allow_url_open选项配置的影响。如果该配置关闭了,则该函数也就失效了。而curl不受该配置的影响。
curl 可以模拟多种请求,例如:POST数据,表单提交等,用户可以按照自己的需求来定制请求。而fopen / file_get_contents只能使用get方式获取数据。
4.使用框架
使用框架这一块打算以后单独研究,并拿出来单写一篇博客
所有代码挂在我的github上。
参考阅读: