PHP多线程批量采集下载美女图片的实现代码(续)

下面是讲解“PHP多线程批量采集下载美女图片的实现代码(续)”攻略的完整步骤:

一、前置准备
首先我们需要安装扩展,安装php-amqp扩展,这个扩展是使用RabbitMQ必备的,安装方式在官方仓库和pecl都有,我一般使用pecl安装,使用命令“sudo pecl install amqp”,然后在php.ini中添加引入即可。

二、创建消息队列
通过RabbitMQ的管理后台(默认在http://localhost:15672,此处需要安装RabbitMQ Server),创建队列,输入队列名称(如此处使用的女神图片存储队列名称为“girl_images”),然后点击添加队列即可。

三、编写采集代码
在采集代码中,首先我们需要使用curl获取目标网站的html代码内容,然后再通过正则表达式来提取其中的图片链接,之后再将这些图片链接发送到消息队列中保存。

下面是示例代码:

<?php
// 采集网站首页的美女图片链接并存入队列
require_once __DIR__ . '/vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

// 创建rabbitmq连接
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

// 指定队列名称
$queue_name = 'girl_images';

// 声明队列(如果不存在才创建)
$channel->queue_declare($queue_name, false, true, false, false);

// 获取网址
$index_url='http://www.mzitu.com';

// 获取html代码
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $index_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$html = curl_exec($ch);

// 正则表达式提取图片链接
preg_match_all('/<a href="http:\/\/www.mzitu.com\/\d+" target="_blank"><img src="(.*?)"/is', $html, $matches);

// 获取图片链接前缀(一般都会有)
$prefix = 'http:';

// 遍历所有匹配到的图片链接,发送到队列中存储
foreach ($matches[1] as $url) {
    $url = $prefix . $url;
    $msg = new AMQPMessage($url);
    $channel->basic_publish($msg, '', $queue_name);
}

// 关闭rabbitmq连接
$channel->close();
$connection->close();

四、编写下载代码
接着是下载代码部分,从消息队列中获取图片链接,然后通过curl下载图片并保存到指定目录中,需要注意的是需要先获取图片的大小,设定好进度条之后再开始下载。

下面是示例代码:

<?php
// 从队列中获取美女图片链接并下载保存
require_once __DIR__ . '/vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;

// 创建rabbitmq连接
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

// 指定队列名称
$queue_name = 'girl_images';

// 声明队列(如果不存在才创建)
$channel->queue_declare($queue_name, false, true, false, false);

// 设定美女图片的存储目录
$images_dir = __DIR__ . '/images/';
if (!is_dir($images_dir)) {
    mkdir($images_dir);
}

// 设定进度条相关的参数
$total = $channel->queue_declare($queue_name, true)[1];
$progress = new \ProgressBar\Manager(0, $total);

// 消费队列中的数据
$i = 0;
while ($i < $total) {
    $i++;
    // 从消息队列中获取美女图片链接
    $msg = $channel->basic_get($queue_name);
    if ($msg) {
        $url = $msg->body;

        // 获取图片的大小
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 1);
        $result = curl_exec($ch);
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $header = substr($result, 0, $header_size);
        $body = substr($result, $header_size);

        // 通过正则表达式获取图片大小
        preg_match('/Content-Length:\s([\d]+)/is', $header, $matches);
        $size = isset($matches[1]) ? $matches[1] : 0;

        // 检查图片是否已存在
        $image_name = basename($url);
        $image_file = $images_dir . $image_name;
        if (file_exists($image_file)) {
            echo $image_name . ' already exists' . PHP_EOL;
            $channel->basic_ack($msg->delivery_info['delivery_tag']);
            continue;
        }

        // 启动下载进度条
        $progress->update($i);

        // 下载图片并保存到指定目录
        $fp=fopen($image_file,'wb');
        fwrite($fp,$body);
        fclose($fp);

        // 等待一段时间再确认消息已经被消费
        sleep(1);

        // 发送确认消息,标记消息已被消费
        $channel->basic_ack($msg->delivery_info['delivery_tag']);
    }
}

// 关闭rabbitmq连接
$channel->close();
$connection->close();

总结:
以上就是实现批量下载美女图片的完整攻略。为了爬虫的健壮性,建议大家在爬虫程序中添加异常处理机制。此外,对于其他元素的抓取和分析也可以采用类似的方法,通过队列和多线程的方式让程序更灵活、高效、稳定地工作。

本文链接:https://my.lmcjl.com/post/15758.html

展开阅读全文

4 评论

留下您的评论.