下载每个商品链接的所有图片,并保存,结合前面的三部分
import os
import time
import pandas as pd
import requests
import logging
import re
from DrissionPage import ChromiumPage
def download_images_from_csv(file_path, output_dir=r".\images"):
"""
从CSV文件中读取商品标题和图片链接,并将图片下载到对应的文件夹中。
参数:
file_path (str): CSV文件路径。
output_dir (str): 输出文件夹路径,存放下载的图片。默认为.\images
"""
# 配置日志记录
# %(asctime)s占位符表示的当前时间,
# INFO是由%(levelname)s占位符表示的日志级别,
# 而这是一条测试消息就是%(message)s占位符对应的具体消息内容
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s')
# 创建输出目录(如果不存在)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
try:
# 使用pandas读取CSV文件
df = pd.read_csv(file_path)
# 确保数据框中包含 '商品标题' 和 '图片' 列
if '商品标题' not in df.columns or '图片' not in df.columns:
raise ValueError("CSV文件中缺少 '商品标题' 或 '图片' 列")
# 模拟浏览器请求头
headers = {
'User - Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
# 遍历每一行数据
for index, row in df.iterrows():
# 休眠3秒,防止被反爬
time.sleep(3)
# 获取商品标题
title = row['商品标题']
# 获取图片链接
image_url = row['图片']
# 跳过空的图片链接
if pd.isna(image_url):
continue
# 创建以商品标题命名的文件夹
folder_path = os.path.join(output_dir, title)
if not os.path.exists(folder_path):
os.makedirs(folder_path)
# 下载图片
try:
# 监听数据包
# data_bag = f"https://img.alicdn.com/" # 抓包获取
data_bag = f"https://"
chrom.listen.start(data_bag)
# 打开目标网页
chrom.get(image_url)
# print("成功跳转到:" + image_url)
# 等待数据包加载
# print("正在等待数据包加载!!!")
# 在 DrissionPage 的监听功能中,默认情况下,chrom.listen.wait() 方法如果没有指定 timeout 参数,它会永久等待,直到捕获到目标数据包为止。
resp = chrom.listen.wait()
# print("获取到数据包!!!")
# print(resp)
# print("开始尝试解析......")
"""
在DrissionPage库的代码情境中,resp.response.body用于获取捕获到的数据包响应的内容主体。具体解释如下:
resp:它是通过chrom.listen.wait()获取到的数据包对象。这个对象包含了与捕获到的数据包相关的各种信息,如请求头、响应头、响应内容等。
response:resp对象的一个属性,用于访问该数据包的响应部分。响应部分包含了服务器返回给客户端的信息,比如状态码、响应头和响应体等。
body:response对象的属性,代表响应内容的主体部分。
对于 HTTP 请求来说,如果请求的是一个网页,body里可能是 HTML 内容;
如果请求的是 JSON 数据,body里就是 JSON 格式的字符串;
如果请求的是图片、视频等二进制文件,body里就是对应的二进制数据
"""
# 获取响应数据
response_data = resp.response.body
# print("解析成功!!!已获取图片数据!!!准备保存!!!")
# 如果响应数据不为空,则准备保存图片数据!!!
if response_data:
# 从视频链接中提取视频文件名,先按'/'分割取最后一部分
image_name = image_url.split('/')[-1]
# 去除文件名中的非法字符
image_name = re.sub(r'[\\/*?:"<>|]', '', image_name)
# 构建图片保存路径
image_path = os.path.join(folder_path, image_name)
# 将图片写入文件
with open(image_path, 'wb') as f:
f.write(response_data)
logging.info(f"已从该链接:{image_url} - 下载图片: {image_path}")
else:
# 重新下载的最大次数
max_count = 0
while True: # 保证下载成功率百分之百!!!
logging.warning(f"无法下载该链接: {image_url} 的图片")
logging.warning(f"即将尝试重新下载!!!")
time.sleep(5) # 隔5秒再下载,目的是提高成功率!!!
# 监听数据包
data_bag = f"https://img.alicdn.com/"
chrom.listen.start(data_bag)
# 打开目标网页
chrom.get(image_url)
print("成功跳转到:" + image_url)
# 等待数据包加载
print("正在等待数据包加载!!!")
# 在 DrissionPage 的监听功能中,默认情况下,chrom.listen.wait() 方法如果没有指定 timeout 参数,它会永久等待,直到捕获到目标数据包为止。
resp = chrom.listen.wait()
print("获取到数据包!!!")
print(resp)
max_count = max_count + 1 # 重新请求次数增加1
print("开始尝试解析......")
"""
在DrissionPage库的代码情境中,resp.response.body用于获取捕获到的数据包响应的内容主体。具体解释如下:
resp:它是通过chrom.listen.wait()获取到的数据包对象。这个对象包含了与捕获到的数据包相关的各种信息,如请求头、响应头、响应内容等。
response:resp对象的一个属性,用于访问该数据包的响应部分。响应部分包含了服务器返回给客户端的信息,比如状态码、响应头和响应体等。
body:response对象的属性,代表响应内容的主体部分。
对于 HTTP 请求来说,如果请求的是一个网页,body里可能是 HTML 内容;
如果请求的是 JSON 数据,body里就是 JSON 格式的字符串;
如果请求的是图片、视频等二进制文件,body里就是对应的二进制数据
"""
# 获取响应数据
response_data = resp.response.body
print("解析成功!!!已获取图片数据!!!准备保存!!!")
# 如果响应数据不为空,则准备保存图片数据!!!
if response_data:
# 从视频链接中提取视频文件名,先按'/'分割取最后一部分
image_name = image_url.split('/')[-1]
# 去除文件名中的非法字符
image_name = re.sub(r'[\\/*?:"<>|]', '', image_name)
# 构建图片保存路径
image_path = os.path.join(folder_path, image_name)
# 将图片写入文件
with open(image_path, 'wb') as f:
f.write(response_data)
logging.info(f"已成功重新下载该链接:{image_url} - 下载图片路径: {image_path}")
break
if max_count == 2: # 最多重新下载2次
break
# 捕获下载图片过程中的异常
except Exception as e:
logging.error(f"下载图片失败: {image_url}, 错误: {e}")
# 如果文件未找到,记录错误日志
except FileNotFoundError:
logging.error(f"文件未找到: {file_path}")
# 如果CSV文件为空,记录错误日志
except pd.errors.EmptyDataError:
logging.error("CSV文件为空")
# 捕获其他异常并记录错误日志
except Exception as e:
logging.error(f"发生错误: {e}")
# 示例调用
# 实例化浏览器对象
chrom = ChromiumPage()
# 这里设置CSV文件路径,你需要根据实际情况修改,如果是相对路径要确保文件在对应位置
csv_file_path = r".\data\自动化天猫商品链接详情数据.csv"
# 输出目录路径【默认为.\images】,可按需修改,不存在时会自动创建
output_directory = r".\images"
# 调用函数开始下载图片
download_images_from_csv(csv_file_path, output_directory)