Python爬虫-如何将图片和视频保存到本地
Python爬虫保存图片和视频到本地主要涉及网络请求、内容解析和文件操作等步骤。下面将分别介绍这两种媒体资源的保存方法。
图片保存方法
保存图片通常需要先获取网页内容,然后提取图片链接,最后下载并保存到本地文件夹。
使用requests库获取图片内容是最常见的方式,通过二进制写入模式将图片数据保存到本地。首先需要创建保存目录,然后循环下载所有匹配到的图片链接。对于使用懒加载技术的网站,需要注意图片可能存储在data-src属性而非src属性中。
另一种方法是使用urllib库的urlretrieve()函数,它可以直接从网络下载资源到本地,代码更加简洁。
视频保存方法
视频保存与图片类似,但由于视频文件通常较大,需要使用流式下载来避免内存溢出。
通过设置stream=True参数
import os
import requests
from bs4 import BeautifulSoup
import re
class MediaDownloader:
def __init__(self, save_dir="./downloads"):
self.save_dir = save_dir
self.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"
}
# 创建保存目录
os.makedirs(save_dir, exist_ok=True)
def download_image(self, img_url, filename=None):
"""下载单张图片并保存到本地"""
try:
if not filename:
filename = img_url.split("/")[-1]
response = requests.get(img_url, headers=self.headers)
if response.status_code == 200:
filepath = os.path.join(self.save_dir, "images", filename)
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'wb') as f:
f.write(response.content)
print(f"图片下载成功: {filename}")
return True
else:
print(f"图片下载失败: {img_url}")
return False
except Exception as e:
print(f"下载图片时出错: {str(e)}")
return False
def download_video(self, video_url, filename=None):
"""下载视频文件(支持大文件和断点续传)"""
try:
if not filename:
filename = video_url.split("/")[-1] or "video.mp4"
filepath = os.path.join(self.save_dir, "videos", filename)
os.makedirs(os.path.dirname(filepath), exist_ok=True)
# 断点续传处理
if os.path.exists(filepath):
file_size = os.path.getsize(filepath)
self.headers['Range'] = f'bytes={file_size}-'
response = requests.get(video_url, headers=self.headers, stream=True)
if response.status_code in [200, 206]: # 200正常,206部分内容
mode = 'ab' if os.path.exists(filepath) else 'wb'
with open(filepath, mode) as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
print(f"视频下载成功: {filename}")
return True
else:
print(f"视频下载失败,状态码: {response.status_code}")
return False
except Exception as e:
print(f"下载视频时出错: {str(e)}")
return False
def extract_media_urls(self, url):
"""从网页中提取图片和视频URL"""
try:
response = requests.get(url, headers=self.headers)
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'html.parser')
# 提取图片URL
image_urls = []
img_tags = soup.find_all('img')
for img in img_tags:
# 优先使用data-src(懒加载),其次使用src
img_url = img.get('data-src') or img.get('src')
if img_url and img_url.startswith(('http', '//')):
if img_url.startswith('//'):
img_url = 'https:' + img_url
image_urls.append(img_url)
# 提取视频URL
video_urls = []
video_tags = soup.find_all('video')
for video in video_tags:
video_url = video.get('src')
if video_url and video_url.startswith(('http', '//')):
if video_url.startswith('//'):
video_url = 'https:' + video_url
video_urls.append(video_url)
# 查找其他可能的视频标签
source_tags = soup.find_all('source')
for source in source_tags:
video_url = source.get('src')
if video_url and video_url.startswith(('http', '//')):
if video_url.startswith('//'):
video_url = 'https:' + video_url
video_urls.append(video_url)
return image_urls, video_urls
except Exception as e:
print(f"提取媒体URL时出错: {str(e)}")
return [], []
def scrape_and_download(self, url):
"""主函数:爬取网页并下载所有媒体资源"""
print(f"开始爬取: {url}")
image_urls, video_urls = self.extract_media_urls(url)
print(f"找到 {len(image_urls)} 张图片")
print(f"找到 {len(video_urls)} 个视频")
# 下载所有图片
for i, img_url in enumerate(image_urls):
print(f"下载图片 {i+1}/{len(image_urls)}")
self.download_image(img_url, f"image_{i+1}.jpg")
# 下载所有视频
for i, video_url in enumerate(video_urls):
print(f"下载视频 {i+1}/{len(video_urls)}")
self.download_video(video_url, f"video_{i+1}.mp4")
print("所有媒体资源下载完成!")
def main():
# 使用示例
downloader = MediaDownloader("./my_downloads")
# 替换为你要爬取的实际URL
target_url = "https://example.com" # 请替换为实际URL
# 开始爬取和下载
downloader.scrape_and_download(target_url)
if __name__ == "__main__":
main()
代码功能说明
1.媒体URL提取:使用BeautifulSoup解析网页HTML,从img和video标签中提取图片和视频链接,特别处理了懒加载图片的data-src属性。
2.图片下载:通过requests库获取图片二进制数据,并以wb模式写入本地文件。
3.视频下载:采用流式下载方式,通过iter_content方法分块处理大文件,避免内存不足。
4.断点续传:通过检查已下载文件大小和设置Range请求头,实现下载中断后的继续下载功能。
5.文件组织:自动创建分类文件夹(images和videos)来保存不同类型的媒体文件。
使用注意事项
在实际使用时,请将示例URL替换为实际要爬取的网站地址。
遵守网站的robots.txt规则,避免对服务器造成过大压力。
对于需要JavaScript渲染的网页,可能需要使用Selenium等工具。
注意版权问题,仅下载允许下载的公开资源。
该实现结合了多个搜索结果中的最佳实践,提供了完整的媒体资源下载解决方案。
更多推荐
所有评论(0)