开发者社区> 仙士可> 正文

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

简介: 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

 */

 

namespace Queue;

 

class MyCurl

{

    private static $url    ''// 访问的url

    private static $oriUrl ''// referer url

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

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

 

    public static function send($url$data array(), $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';

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

    }

 

    /**

     * 基础发起curl请求函数

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

     */

    private static function doRequest($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请求

     */

    public static function getRequest()

    {

        return self::doRequest(0);

    }

 

    /**

     * 发起post请求

     */

    public static function postRequest()

    {

        return self::doRequest(1);

    }

 

    /**

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

     *

     * @param array $postData

     */

    public static function dealPostData($postData)

    {

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

        foreach ($postData as $k => $v) {

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

        }

        $postData substr($o, 0, -1);

        return $postData;

    }

 

    /**

     * 发起put请求

     */

    public static function putRequest($param)

    {

        return self::doRequest(2);

    }

 

    /**

     * 发起delete请求

     */

    public static function deleteRequest($param)

    {

        return self::doRequest(3);

    }

}

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

<?php

 

/**

 * Created by PhpStorm.

 * User: tioncico

 * Date: 2018/2/28 0028

 * Time: 19:54

 */

namespace Queue;

use QL\QueryList;

 

class Down

{

    private static $instance;

    public function __construct() {

 

    }

 

    static function getInstance(){

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

            return self::$instance;

        }else{

            self::$instance new Down();

            return self::$instance;

        }

    }

 

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

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

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

//        var_dump($res);

        $rules array(

            //采集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";

        }

    }

 

    public static function add_img_file($id,$url){

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

        $rules array(

            //采集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

namespace Queue;

class Redis

{

    private $con;

    protected static $instance;

    protected $tryConnectTimes = 0;

    protected $maxTryConnectTimes = 3;

    function __construct()

    {

        $this->connect();

    }

    function connect(){

        $this->tryConnectTimes++;

        $conf array(

            "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");

                return null;

            }

        }

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

    }

    static function getInstance(){

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

            return self::$instance;

        }else{

            self::$instance new Redis();

            return self::$instance;

        }

    }

    function rPush($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{

                return false;

            }

 

        }

 

    }

    function lPop($key){

        try{

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

        }catch(\Exception $e){

            $this->connect();

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

                return $this->lPop($key);

            }else{

                return false;

            }

 

        }

    }

    function lSize($key){

        try{

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

            return $ret;

        }catch(\Exception $e){

            $this->connect();

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

                return $this->lSize($key);

            }else{

                return false;

            }

 

        }

    }

    function getRedisConnect(){

        return $this->con;

    }

    function ping(){

        try{

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

            if(!empty($ret)){

                $this->tryConnectTimes = 0;

                return true;

            }else{

                return false;

            }

        }catch(\Exception $e){

            return false;

        }

    }

 

}

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
基于springboot+mysql+redis+bootstrap的精美个人技术博客网站
基于springboot+mysql+redis+bootstrap的精美个人技术博客网站
35 0
WebSocket + Redis简单快速实现Web网站单设备登录功能
单设备登录作用很明显,就是为了保护用户账号安全,今天我们不说手机APP,我们来说说PC Web网站如何简单快速实现这种效果。本篇文章重点是实现单设备登录,内容未涉及WebSocket + Redis的概念和使用方法。限于本人经验,如有错误,欢迎指正。
129 0
部署论坛项目并使用redis缓存加速网站访问流量
部署discuz并使用redis加速 1.部署LNMP环境 1.1.准备yum环境
111 0
初次使用阿里云服务器部署redis,部署网站有感
初次使用阿里云服务器部署redis,部署网站有感
108 0
阿里云服务器搭配宝塔面板安装Redis为网站提速
一、Redis是什么?为什么可以提高网站速度? 按照网上的统一说法:Redis是一款内存高速缓存数据库。Redis全称为:Remote Dictionary Server(远程数据服务)Redis以内存作为数据存储介质,所以读写数据的效率极高,远远超过数据库。
4791 0
Flume+Kafka+Flink+Redis构建大数据实时处理系统:实时统计网站PV、UV展示
1.大数据处理的常用方法 大数据处理目前比较流行的是两种方法,一种是离线处理,一种是在线处理,基本处理架构如下: 在互联网应用中,不管是哪一种处理方式,其基本的数据来源都是日志数据,例如对于web应用来说,则可能是用户的访问日志、用户的点击日志等。
17706 0
Redis简单案例(二) 网站最近的访问用户
原文:Redis简单案例(二) 网站最近的访问用户   我们有时会在网站中看到最后的访问用户、最近的活跃用户等等诸如此类的一些信息。本文就以最后的访问用户为例, 用Redis来实现这个小功能。在这之前,我们可以先简单了解一下在oracle、sqlserver等关系型数据库中是怎么实现的。
962 0
Redis简单案例(一) 网站搜索的热搜词
原文:Redis简单案例(一) 网站搜索的热搜词   对于一个网站来说,无论是商城网站还是门户网站,搜索框都是有一个比较重要的地位,它的存在可以说是 为了让用户更快、更方便的去找到自己想要的东西。对于经常逛这个网站的用户,当然也会想知道在这里比较“火” 的东西是什么,这个时候我们搜索框上的热词就起作用了。
1093 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
高并发分布式缓存Redis6.0
立即下载
阿里云Redis服务助力游戏行业发展--王义成
立即下载
国内开发者与Redis开源社区的发展
立即下载