下面是讲解“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 评论