日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

多线程方式采集搜狗高清壁纸的实现

發(fā)布時間:2023/12/13 综合教程 22 生活家
生活随笔 收集整理的這篇文章主要介紹了 多线程方式采集搜狗高清壁纸的实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

上一篇,完成了Windows下PHP多線程擴(kuò)展pthreads的安裝,下面就利用多線程進(jìn)行圖片的采集

一、實現(xiàn)前準(zhǔn)備工作

1、打開搜狗圖片網(wǎng)站

打開控制臺,分析異步請求數(shù)據(jù)規(guī)律

2、搜狗圖片存儲數(shù)據(jù)表結(jié)構(gòu)創(chuàng)建

打開搜狗異步請求鏈接,查看響應(yīng)結(jié)果中的json數(shù)據(jù)


根據(jù)上圖中圖片詳情創(chuàng)建搜狗圖片數(shù)據(jù)表結(jié)構(gòu)sql語句如下:

CREATE TABLE `sougou_pic` (
  `sougou_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '表主鍵id',
  `id` int(11) DEFAULT NULL COMMENT '搜過網(wǎng)站圖片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、錄入搜狗圖片到數(shù)據(jù)庫

采集代碼這里省略,需要注意的是,采集過程中防止超時的存在(主要可能還是搜狗有做簡單反爬蟲處理),超時采集不到就延時5秒繼續(xù)采集。

下面是錄入完成后數(shù)據(jù)表一覽

二、多線程方式下載數(shù)據(jù)庫中已錄入的搜狗圖片

1、采用Yii2框架實現(xiàn)

Yii2框架控制臺(console)下創(chuàng)建命令行可執(zhí)行腳本文件SougouController.php,代碼如下:


<?php

namespace consolecontrollers;

use yii;
use yiiconsoleController;
use commonmodelsSougouPic as M;
use commoncomponentSougouPthreads;
use yiiconsoleException;

class SougouController extends Controller
{
    /**
     * 下載搜狗圖片
     */
    public function actionDownload()
    {
        try{
            $stime=microtime(true);

            $arrsSougouPic = M::myTables();//3500,6030,9636
            echo '圖片總數(shù)量共: '.count($arrsSougouPic).PHP_EOL;

            //線程池
            $pool = array();

            foreach ($arrsSougouPic as $member){
                $sougou_id = $member['sougou_id'];
                while (true){
                    if(count($pool) < 5){
                        //要下載的原圖
                        $ori_pic_url = $member['ori_pic_url'];
                        $pool[$sougou_id] = new SougouPthreads($member['sougou_id'], $member['size'], $member['title'], $ori_pic_url, $member['width'], $member['height']);
                        $pool[$sougou_id]->start();
                        break;
                    }else{
                        foreach ( $pool as $name => $worker){
                            if(! $worker->isRunning()){
                                unset($pool[$name]);
                            }
                        }
                    }
                }
            }

            $arrsSougouPic = null;

            echo "Download completed!".PHP_EOL;

            $etime=microtime(true);//獲取程序執(zhí)行結(jié)束的時間
            $total=$etime-$stime;   //計算差值
            echo '共運行時間:'.$total.'秒'.PHP_EOL;
        } catch (Exception $e) {
            echo '【' , date('H:i:s') , '】', '【系統(tǒng)錯誤】', $e->getMessage(), "".PHP_EOL;
        }
    }
    
}

搜狗多線程類繼承線程類,SougouPthreads.php代碼如下


<?php
namespace commoncomponent;

use Yii;
use Thread;

class SougouPthreads extends Thread
{
    public $running = false;
    public $sougou_id = '';
    public $title = '';
    public $size;
    public $ori_pic_url = '';
    public $width = '';
    public $height = '';
    protected $saveDir = '';
    protected $downloadFailedTxt;

    public function __construct($sougou_id, $size, $title, $ori_pic_url, $width, $height)
    {
        $this->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;
        }
        //獲取遠(yuǎn)程文件
        $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 <renzhicai.sz@mopon.cn>
     * 自定義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);   //只需要設(shè)置一個秒的數(shù)量就可以
        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項目根目錄執(zhí)行控制臺腳本(console)

//將執(zhí)行結(jié)果記錄到文本文件中
php yii sougou/download > sougoudownloadinfo.txt

3、下載完后效果一覽

自動按尺寸歸類圖片

【參考資料】

PHP Pthread多線程 操作

總結(jié)

以上是生活随笔為你收集整理的多线程方式采集搜狗高清壁纸的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。