php使用redis异步队列爬取网站图片的教程(1)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: php使用redis异步队列爬取网站图片的教程

相信大家都很想取爬取某些网站的内容,图片,但是不知道怎么动手,以下的教程就是从0开始教大家爬取某个网站图片


准备工作:

curl封装类(需要curl扩展);

php redis扩展(用于使用redis)

redis服务器(用于队列)

QueryList插件:https://querylist.cc/  实现php选择html DOM

运行环境:本文在php-cli模式下运行,不需要考虑超时时间

首先,建立个爬取的目录(Queue)


增加Mycurl.php

<?php

/**

 * Created by PhpStorm.

 * User: tioncico

 * Date: 2018/2/26 0026

 * Time: 21:34

 */

 

namespaceQueue;

 

classMyCurl

{

    privatestatic$url    ''// 访问的url

    privatestatic$oriUrl''// referer url

    privatestatic$data   array(); // 可能发出的数据 post,put

    privatestatic$method// 访问方式,默认是GET请求

 

    publicstaticfunctionsend($url$dataarray(), $method'get')

    {

        if(!$urlexit('url can not be null');

        self::$url    $url;

        self::$method$method;

        $urlArr       parse_url($url);

        self::$oriUrl$urlArr['scheme'] . '://'$urlArr['host'];

        self::$data   $data;

        if(!in_array(

            self::$method,

            array(

                'get',

                'post',

                'put',

                'delete'

            )

        )

        ) {

            exit('error request method type!');

        }

 

        $func= self::$method'Request';

        returnself::$func(self::$url);

    }

 

    /**

     * 基础发起curl请求函数

     * @param int $is_post 是否是post请求

     */

    privatestaticfunctiondoRequest($is_post= 0)

    {

        $ch= curl_init();//初始化curl

        curl_setopt($ch, CURLOPT_URL, self::$url);//抓取指定网页

        curl_setopt($ch, CURLOPT_AUTOREFERER, true);

        // 来源一定要设置成来自本站

        curl_setopt($ch, CURLOPT_REFERER, self::$oriUrl);

 

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上

        if($is_post== 1) curl_setopt($ch, CURLOPT_POST, $is_post);//post提交方式

        if(!empty(self::$data)) {

            self::$data= self::dealPostData(self::$data);

            curl_setopt($ch, CURLOPT_POSTFIELDS, self::$data);

        }

 

        $data= curl_exec($ch);//运行curl

        curl_close($ch);

        return$data;

    }

 

    /**

     * 发起get请求

     */

    publicstaticfunctiongetRequest()

    {

        returnself::doRequest(0);

    }

 

    /**

     * 发起post请求

     */

    publicstaticfunctionpostRequest()

    {

        returnself::doRequest(1);

    }

 

    /**

     * 处理发起非get请求的传输数据

     *

     * @param array $postData

     */

    publicstaticfunctiondealPostData($postData)

    {

        if(!is_array($postData)) exit('post data should be array');

        foreach($postDataas$k=> $v) {

            $o.= "$k=". urlencode($v) . "&";

        }

        $postDatasubstr($o, 0, -1);

        return$postData;

    }

 

    /**

     * 发起put请求

     */

    publicstaticfunctionputRequest($param)

    {

        returnself::doRequest(2);

    }

 

    /**

     * 发起delete请求

     */

    publicstaticfunctiondeleteRequest($param)

    {

        returnself::doRequest(3);

    }

}

下载图片类Down.php(看完下面的教程再看这个类说明)

<?php

 

/**

 * Created by PhpStorm.

 * User: tioncico

 * Date: 2018/2/28 0028

 * Time: 19:54

 */

namespaceQueue;

useQL\QueryList;

 

classDown

{

    privatestatic$instance;

    publicfunction__construct() {

 

    }

 

    staticfunctiongetInstance(){

        if(is_object(self::$instance)){

            returnself::$instance;

        }else{

            self::$instancenewDown();

            returnself::$instance;

        }

    }

 

    publicstaticfunctionadd_img($str){//这里进来的是详情,每个详情有n页,每页一张高清大图

        $idsubstr($str,strripos($str,'/')+1);//截取出id

        $res   = \Queue\MyCurl::send($strarray('ip'=>'127.0.0.1'), 'get');

//        var_dump($res);

        $rulesarray(

            //采集id为one这个元素里面的纯文本内容

            'page'=> array(

                '.pagenavi span',

                'html'

            ),

        );

        $hj    = QueryList::Query($res$rules);

        $data$hj->getData(function($x) {//总页数

            return$x;

        });

        //获取到了页面元素

        $count$data[count($data)-2]['page'];//这个是获取倒数第2个,倒数第2个是总页数

        echo'共有'.$count."张图\n";

        for($i=1;$i<=$count;$i++){

            $url$str.'/'.$i;

            self::add_img_file($id,$url);//开始保存图片

            echo"{$i}/$count\n";

        }

    }

 

    publicstaticfunctionadd_img_file($id,$url){

        $res   = \Queue\MyCurl::send($urlarray('ip'=>'127.0.0.1','Referer'=>'http://www.mzitu.com/116663/2'), 'get');

        $rulesarray(

            //采集id为one这个元素里面的纯文本内容

            'img_url'=> array(

                '.main-image img',

                'src'

            ),

        );//获取到了高清图片链接

        $hj    = QueryList::Query($res$rules);

        $data$hj->getData(function($x) {//总页数

            return$x;

        });

        $img_url$data[0]['img_url'];

        $path= BASE_DIR.'/img/'.$id.'/';

        @mkdir($path,0777);//新建文件夹存取图片TODO缺少存进数据库

        chmod($path,0777);

        $file_path$path.substr($img_url,strripos($img_url,'/')+1);

//        var_dump($file_path);

        $data= MyCurl::send($img_url);

        $write= @fopen($file_path"w+");

        fwrite($write$data);

        fclose($write);//存取图片

    }

 

}


封装redis.php类

<?php

namespaceQueue;

classRedis

{

    private$con;

    protectedstatic$instance;

    protected$tryConnectTimes= 0;

    protected$maxTryConnectTimes= 3;

    function__construct()

    {

        $this->connect();

    }

    functionconnect(){

        $this->tryConnectTimes++;

        $confarray(

            "HOST"=>'127.0.0.1',

            "PORT"=>6379,

            "AUTH"=>""

        );

        $this->con = new\Redis();

        $this->con->connect($conf['HOST'], $conf['PORT'],2);

        $this->con->auth($conf['AUTH']);

        if(!$this->ping()){

            if($this->tryConnectTimes <= $this->maxTryConnectTimes){

                return$this->connect();

            }else{

                trigger_error("redis connect fail");

                returnnull;

            }

        }

        $this->con->setOption(\Redis::OPT_SERIALIZER,\Redis::SERIALIZER_PHP);

    }

    staticfunctiongetInstance(){

        if(is_object(self::$instance)){

            returnself::$instance;

        }else{

            self::$instancenewRedis();

            returnself::$instance;

        }

    }

    functionrPush($key,$val){

        try{

            return$this->con->rpush($key,$val);

//            return $ret;

        }catch(\Exception $e){

            $this->connect();

            if($this->tryConnectTimes <= $this->maxTryConnectTimes){

                return$this->rPush($key,$val);

            }else{

                returnfalse;

            }

 

        }

 

    }

    functionlPop($key){

        try{

            return$this->con->lPop($key);

        }catch(\Exception $e){

            $this->connect();

            if($this->tryConnectTimes <= $this->maxTryConnectTimes){

                return$this->lPop($key);

            }else{

                returnfalse;

            }

 

        }

    }

    functionlSize($key){

        try{

            $ret$this->con->lSize($key);

            return$ret;

        }catch(\Exception $e){

            $this->connect();

            if($this->tryConnectTimes <= $this->maxTryConnectTimes){

                return$this->lSize($key);

            }else{

                returnfalse;

            }

 

        }

    }

    functiongetRedisConnect(){

        return$this->con;

    }

    functionping(){

        try{

            $ret$this->con->ping();

            if(!empty($ret)){

                $this->tryConnectTimes = 0;

                returntrue;

            }else{

                returnfalse;

            }

        }catch(\Exception $e){

            returnfalse;

        }

    }

 

}

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
NoSQL Redis 数据安全/隐私保护
Redis 最流行的图形化界面下载及使用超详细教程(带安装包)! redis windows客户端下载
文章提供了Redis最流行的图形化界面工具Another Redis Desktop Manager的下载及使用教程,包括如何下载、解压、连接Redis服务器以及使用控制台和查看数据类型详细信息。
159 6
Redis 最流行的图形化界面下载及使用超详细教程(带安装包)! redis windows客户端下载
|
2月前
|
NoSQL Redis 数据库
Redis 图形化界面下载及使用超详细教程(带安装包)! redis windows下客户端下载
文章提供了Redis图形化界面工具的下载及使用教程,包括如何连接本地Redis服务器、操作键值对、查看日志和使用命令行等功能。
156 0
Redis 图形化界面下载及使用超详细教程(带安装包)! redis windows下客户端下载
|
1月前
|
设计模式 NoSQL Go
Redis 实现高效任务队列:异步队列与延迟队列详解
本文介绍了如何使用 Redis 实现异步队列和延迟队列。通过 Go 语言的 `github.com/go-redis/redis` 客户端,详细讲解了 Redis 客户端的初始化、异步队列的实现和测试、以及延迟队列的实现和测试。文章从基础连接开始,逐步构建了完整的队列系统,帮助读者更好地理解和应用这些概念,提升系统的响应速度和性能。
44 6
|
1月前
|
XML 安全 PHP
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。
|
1月前
|
存储 NoSQL PHP
PHP与Redis结合使用,提升数据存储性能
随着互联网应用的发展,PHP与Redis的结合成为提升数据存储性能的重要手段。PHP作为流行的服务器端语言,常用于网站开发;Redis作为高性能内存数据库,以其快速读写能力,有效优化数据访问速度,减轻数据库压力。两者结合通过缓存机制显著提升应用响应速度,支持高并发场景下的稳定性和可扩展性。
|
1月前
|
存储 NoSQL 关系型数据库
PHP 使用 Redis
10月更文挑战第22天
34 6
|
2月前
|
缓存 NoSQL Java
springboot的缓存和redis缓存,入门级别教程
本文介绍了Spring Boot中的缓存机制,包括使用默认的JVM缓存和集成Redis缓存,以及如何配置和使用缓存来提高应用程序性能。
121 1
springboot的缓存和redis缓存,入门级别教程
|
2月前
|
tengine 应用服务中间件 Linux
Tengine、Nginx安装PHP命令教程
要在阿里云Linux上安装PHP,请先更新YUM源并启用PHP 8.0仓库,然后安装PHP及相关扩展。通过`php -v`命令验证安装成功后,需修改Nginx配置文件以支持PHP,并重启服务。最后,创建`phpinfo.php`文件测试安装是否成功。对于CentOS系统,还需安装EPEL源和Remi仓库,其余步骤类似。完成上述操作后,可通过浏览器访问`http://IP地址/phpinfo.php`测试安装结果。
|
2月前
|
消息中间件 存储 NoSQL
如何用Redis实现延迟队列?
综上所述,通过Redis的有序集合和一些基本命令,我们可以轻松地构建出功能完善的延迟队列系统。根据具体需求,可以进一步优化和扩展,以满足高性能和高可靠性的业务需求。
59 1
|
2月前
|
存储 NoSQL Unix
Redis 教程
10月更文挑战第13天
36 0