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
目录
相关文章
|
1月前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
160 79
|
17天前
|
前端开发 API PHP
PHP网编程:guzzle的鉴权和异步操作实践。
Guzzle是一个强大且灵活的HTTP客户端库,它可以方便地发送HTTP请求,并且其对异步请求和各类鉴权方式的支持使其成为处理HTTP请求的理想工具。你需要了解和掌握Guzzle的异步操作并发请求和鉴权方式,以便在实际的开发中得心应手地处理HTTP请求。
47 13
|
2月前
|
缓存 监控 算法
内网监控管理软件:PHP 语言队列算法揭秘
在数字化办公环境中,内网监控管理软件对企业的稳定运行和信息安全至关重要。本文深入介绍PHP中的队列算法及其在内网监控软件中的应用,包括监控数据收集、任务调度和日志记录等场景,通过代码示例展示其实现方法。队列算法可提高性能、保证数据顺序并实现异步处理,为企业提供高效的安全保障。
33 1
|
3月前
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
基于springboot+thymeleaf+Redis仿知乎网站问答项目源码
186 36
|
4月前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
268 26
|
4月前
|
PHP 计算机视觉 UED
Buzz库:PHP图像处理中的异步图像下载和保存
Buzz库:PHP图像处理中的异步图像下载和保存
|
5月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
105 5
|
5月前
|
存储 NoSQL PHP
PHP与Redis结合使用,提升数据存储性能
随着互联网应用的发展,PHP与Redis的结合成为提升数据存储性能的重要手段。PHP作为流行的服务器端语言,常用于网站开发;Redis作为高性能内存数据库,以其快速读写能力,有效优化数据访问速度,减轻数据库压力。两者结合通过缓存机制显著提升应用响应速度,支持高并发场景下的稳定性和可扩展性。
|
5月前
|
存储 NoSQL 关系型数据库
PHP 使用 Redis
10月更文挑战第22天
100 6
|
JSON NoSQL 前端开发
Redis简单案例(一) 网站搜索的热搜词
原文:Redis简单案例(一) 网站搜索的热搜词   对于一个网站来说,无论是商城网站还是门户网站,搜索框都是有一个比较重要的地位,它的存在可以说是 为了让用户更快、更方便的去找到自己想要的东西。对于经常逛这个网站的用户,当然也会想知道在这里比较“火” 的东西是什么,这个时候我们搜索框上的热词就起作用了。
1472 0