上一篇,完成了Windows下PHP多线程扩展
pthreads
的安装,下面就利用多线程进行图片的采集
一、实现前准备工作
1、打开
打开控制台,分析异步请求数据规律
2、搜狗图片存储数据表结构创建
打开,查看响应结果中的json数据
根据上图中图片详情创建搜狗图片数据表结构sql语句如下:CREATE TABLE `sougou_pic` ( `sougou_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '表主键id', `id` int(11) DEFAULT NULL COMMENT '搜过网站图片id', `did` int(10) DEFAULT NULL, `thumbUrl` varchar(255) DEFAULT NULL, `thumb_width` int(10) DEFAULT NULL, `thumb_height` int(10) DEFAULT NULL, `sthumbUrl` varchar(255) DEFAULT NULL, `sthumb_width` int(10) DEFAULT NULL, `sthumb_height` int(10) DEFAULT NULL, `bthumbUrl` varchar(255) DEFAULT NULL, `bthumb_width` int(10) DEFAULT NULL, `bthumb_height` int(10) DEFAULT NULL, `pic_url` varchar(255) DEFAULT NULL, `width` int(10) DEFAULT NULL, `height` int(10) DEFAULT NULL, `size` int(10) DEFAULT NULL, `ori_pic_url` varchar(255) DEFAULT NULL, `ext_url` varchar(255) DEFAULT NULL, `page_title` varchar(64) DEFAULT NULL, `page_url` varchar(255) DEFAULT NULL, `title` varchar(64) DEFAULT NULL, `tags` varchar(64) DEFAULT NULL, `group_mark` varchar(8) DEFAULT NULL, `group_index` int(10) DEFAULT NULL, `publish_time` int(10) DEFAULT NULL, `surr1` varchar(16) DEFAULT NULL, `surr2` varchar(16) DEFAULT NULL, `category` varchar(16) DEFAULT NULL, `weight` int(10) DEFAULT NULL, `deleted` int(10) DEFAULT NULL, `waplink` varchar(255) DEFAULT NULL, `weblink` varchar(255) DEFAULT NULL, `intime` int(10) DEFAULT NULL COMMENT '添加时间', `pfrom` varchar(255) DEFAULT '', PRIMARY KEY (`sougou_id`)) ENGINE=InnoDB AUTO_INCREMENT=11088 DEFAULT CHARSET=utf8;
3、录入搜狗图片到数据库
采集代码这里省略,需要注意的是,采集过程中防止超时的存在(主要可能还是搜狗有做简单反爬虫处理),超时采集不到就延时5秒继续采集。
下面是录入完成后数据表一览
二、多线程方式下载数据库中已录入的搜狗图片
1、采用Yii2
框架实现
- 在
Yii2
框架控制台(console
)下创建命令行可执行脚本文件SougouController.php
,代码如下:
start(); break; }else{ foreach ( $pool as $name => $worker){ if(! $worker->isRunning()){ unset($pool[$name]); } } } } } $arrsSougouPic = null; echo "Download completed!".PHP_EOL; $etime=microtime(true);//获取程序执行结束的时间 $total=$etime-$stime; //计算差值 echo '共运行时间:'.$total.'秒'.PHP_EOL; } catch (Exception $e) { echo '【' , date('H:i:s') , '】', '【系统错误】', $e->getMessage(), "".PHP_EOL; } } }
- 搜狗多线程类继承线程类,
SougouPthreads.php
代码如下
sougou_id = $sougou_id; $this->size = $size; $this->title = $title; $this->ori_pic_url = $ori_pic_url; $this->width = $width; $this->height = $height; $this->saveDir.='./static/sougouImages/'.date('Y-m-d').'/'.$this->width.'_'.$this->height.'/'; $this->downloadFailedTxt = $this->saveDir.'1_downloadfailedlist.txt'; if(!is_dir($this->saveDir)){ mkdir($this->saveDir, 0777, true); chmod($this->saveDir, 0777); } } public function run() { //下载 $return = $this->downloadImage(); if (!$return) { echo $this->ori_pic_url.' Download failed'.PHP_EOL; }else{ echo $this->ori_pic_url.' Download completed'.PHP_EOL; } } /** * 下载图片 * @return bool */ public function downloadImage() { //图片后缀 $basename = basename($this->ori_pic_url); $dot = strrpos($basename, '.'); $imageExt = substr($basename, $dot); $imageTitle = substr($basename, 0, $dot); if(strlen($this->title)<2){ //图片名称 $imageName = $imageTitle.'_'.$this->sougou_id; }else{ //图片名称 $imageName = $this->title.'_'.$this->sougou_id; } $imageName = iconv('UTF-8', 'GBK', $imageName); //保存图片路径及名称 $filename = $this->saveDir.$imageName.$imageExt; //判断文件是否已下载 if(file_exists($filename)){ file_put_contents($this->downloadFailedTxt, $this->ori_pic_url.' --文件已下载'.PHP_EOL, FILE_APPEND); return true; } //获取远程文件 $imgContent = $this->myCurl($this->ori_pic_url); if(!$imgContent){ return false; } //保存图片到本地 $return=file_put_contents($filename, $imgContent); if(!file_exists($filename)){ //记录下载失败的图片信息 file_put_contents($this->downloadFailedTxt, $this->ori_pic_url.' --下载失败'.PHP_EOL, FILE_APPEND); return false; } //图片大小与录入时记录的图片大小不一致,说明图片下载失败 if(filesize($filename) != $this->size){ //下载图片不完整,删除 unlink($filename); file_put_contents($this->downloadFailedTxt, $this->ori_pic_url.' --下载图片不完整'.PHP_EOL, FILE_APPEND); return false; } return true; } /** * @author RenZhicai* 自定义curl请求 * @param string $url * @return mixed */ public function myCurl($url='') { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT,60); //只需要设置一个秒的数量就可以 if(preg_match('/https:\/\//', $url)){ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //这个是重点。 } curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'); $output = curl_exec($ch); if($output === false){ //记录curl请求失败的详情 $errorInfo = "cURL Error: ".curl_error($ch); file_put_contents('curl_error_'.date('Ymd').'.txt', $errorInfo, FILE_APPEND); } curl_close($ch); return $output; }}
2、在Yii2项目根目录执行控制台脚本(console
)
//将执行结果记录到文本文件中php yii sougou/download > sougoudownloadinfo.txt
3、下载完后效果一览
自动按尺寸归类图片