【原创】使用Querylist爬取网站缩略图

// 采集并将13页列表中的图片下载到本地
public function downloadImages(){
    //参数:$path 为图片本地保存路径
    $ql = QueryList::getInstance();
    $ql->bind('downloadImage',function ($path){
        $data = $this->getData()->map(function ($item) use($path){
            $item['image'] = $file = 'https://www.xxx.com'.$item['image'];
            $filename = pathinfo($file,PATHINFO_BASENAME);
            //获取图片
            $url = $item['image'];
            $agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)';
            $img = $this->dealCurl($url,$agent);
            if(!is_dir($path)){
                @mkdir($path);
            }
            $localPath = $path.'/'.$filename;
            //保存图片到本地路径
            file_put_contents($localPath,$img);
            //data数组中新增一个自定义的本地路径字段
            $item['local_path'] = $localPath;
            return $item;
        });
        //更新data属性
        $this->setData($data);
        return $this;
    });
    $ql->bind('dealCurl',function ($url,$agent = false){
        $ch = curl_init();
        if(!empty($agent)){
            curl_setopt($ch, CURLOPT_USERAGENT, $agent);
        }
        curl_setopt ($ch, CURLOPT_URL, $url);
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,10);
        // 抓取URL并把它传递给浏览器
        $content = curl_exec($ch);
        if ($content  === false) {
            return "网络请求出错: " . curl_error($ch);
            exit();
        }
        //关闭cURL资源,并且释放系统资源
        curl_close($ch);
        return $content;
    });
    $range = '.independent-xxx-right li'; // 测试网站的切片区域(即缩略图列表的父元素样式)
    for($i = 1;$i < 14;$i++){
        $url = "https://www.xxx.com/xxx/0/p/$i.html";
        $ql->get($url)->rules([
            'image' => ['.independent-PracticeCourse-contentli-top img','src']
        ])->range($range)->query()->downloadImage('img')->getData();
    }
}

注意:
1.之前没有设置agent时,下载下来的图片损坏,经调试发现实际上没有爬取到,得到403 forbidden的提示,加了agent之后,图片显示正常。
2.原本是写了一个dealCurl方法的,仔细看过之后发现是在map()中调用,这样是不行的,因此写了一个bind的dealCurl方法,它可以在map中使用$this调用。

点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注