PHP实现的一个简单的爬虫

这个小爬虫的功能是抓取目标网页的url,并实现递归爬。这个小demo是参照网友的代码然后自己改了一下,由于网上版本太多,我就不@原来的作者了(我不知道谁才是真正的作者)

下面是代码:

<?php
//爬虫类
class Crawler{
    private $url;
    public function __construct($url){
        if(!preg_match("/^(http)s?/", $url)){
            $url = "http://".$url;
        }
        $this->url = $url;
    }
    //从给定的url中获取html内容
    protected function _getUrlContent($url){
        @$handle = fopen($url, "r");
        if(error_get_last()){//捕获异常(不一定是错误)
            $err = new Exception("你的URL好像不对!要不换一个?");
            echo $err->getMessage();
            return;
        }
        if($handle){
            $content = stream_get_contents($handle,1024*1024);//将资源流读入字符串
            return $content;
        }else{
            return false;
        }   
    }
    //从html内容中筛选链接
    protected function _filterUrl($web_content){
        $reg_tag_a = '/<[a|A].*?href=[\'\"]{0,1}([^>\'\"\ ]*).*?>/';
        $result = preg_match_all($reg_tag_a,$web_content,$match_result);
        if($result){
            return $match_result[1];
        }
    }
    //判断是否是完整的url
    protected function _judgeURL($url){
        $url_info = parse_url($url);
        if(isset($url_info['scheme'])||isset($url_info['host'])){
            return true;
        }
        return false;
    }
    //修正相对路径
    protected function _reviseUrl($base_url,$url_list){
        $url_info = parse_url($base_url);//分解url中的各个部分
        unset($base_url);
        $base_url = isset($url_info["scheme"])?$url_info["scheme"].'://':"";//$url_info["scheme"]为http、ftp等
        if(isset($url_info["user"]) && isset($url_info["pass"])){//记录用户名及密码的url
            $base_url .= $url_info["user"].":".$url_info["pass"]."@";
        }
        $base_url .= isset($url_info["host"])?$url_info["host"]:"";//$url_info["host"]域名
        if(isset($url_info["port"])){//$url_info["port"]端口,8080等
            $base_url .= ":".$url_info["port"];
        }
        $base_url .= isset($url_info["path"])?$url_info["path"]:"";//$url_info["path"]路径
        //目前为止,绝对路径前面已经组装完
        if(is_array($url_list)){
            foreach ($url_list as $url_item) {
                // if(preg_match('/^(http)s?/',$url_item)){
                if($this->_judgeURL($url_item)){
                    //已经是完整的url
                    $result[] = $url_item;
                }else {
                    //不完整的url
                    $real_url = $base_url.$url_item;
                    $result[] = $real_url;
                }
            }
            return $result;
        }else {
            return;
        }
    }
    //爬虫
    public function crawler(){
        $content = $this->_getUrlContent($this->url);
        if($content){
            $url_list = $this->_reviseUrl($this->url,$this->_filterUrl($content));
            if($url_list){
                return $url_list;
            }else {
                return ;
            }
        }else{
            return ;
        }
    }
}


$fp_puts = fopen("url.txt","ab");//记录url列表
$fp_gets = fopen("url.txt","r");//保存url列表
$current_url = "www.baidu.com";
do{
    $Crawler = new Crawler($current_url);
    $url_arr = $Crawler->crawler();
    if($url_arr){
        foreach ($url_arr as $url) {
            fputs($fp_puts,$url."\n");
        }
    }
}while ($current_url = fgets($fp_gets,1024));//不断获得url
// echo "<pre>";
// var_dump($url_arr);
// echo "<pre/>";
?>

由于在循环的时候要new的对象可能会很多,当时想的是用单例模式解决,以免内存开销太大,后来嫌麻烦就不了了之了。。。。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值