HOOOS

Python爬虫实战:抓取网站图片并按文件夹智能分类保存

0 2 爬虫小王子 Python爬虫图片抓取文件夹分类
Apple

想把喜欢的网站上的图片都下载下来?想让这些图片井井有条地躺在你的硬盘里,而不是乱糟糟地堆在一起?没问题!今天就来手把手教你用Python写一个爬虫,它可以自动抓取网站上的所有图片,并且按照文件夹分类保存,让你的收藏整洁又高效。

准备工作

首先,确保你已经安装了Python环境。然后,我们需要安装几个强大的库来帮助我们完成任务:

  • requests: 用于发送HTTP请求,获取网页内容。
  • Beautiful Soup 4 (bs4): 用于解析HTML和XML文档,方便我们提取图片链接。
  • os: 用于创建文件夹,保存图片。
  • urllib.parse: 用于处理URL,拼接完整的图片链接。

你可以使用pip命令来安装这些库:

pip install requests beautifulsoup4

核心代码

下面是完整的Python代码,我会一步一步地解释它的功能:

import requests
from bs4 import BeautifulSoup
import os
from urllib.parse import urljoin, urlparse


def is_valid(url):
    '''
    判断URL是否有效
    '''
    parsed = urlparse(url)
    return bool(parsed.netloc) and bool(parsed.scheme)


def get_all_images(url):
    '''
    返回页面中所有图片的URL
    '''
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功
    except requests.exceptions.RequestException as e:
        print(f"请求 {url} 失败: {e}")
        return []

    soup = BeautifulSoup(response.content, 'html.parser')
    urls = []
    for img in soup.find_all('img'):
        img_url = img.attrs.get('src')
        if not img_url:
            # 如果<img>标签没有src属性,则跳过
            continue

        img_url = urljoin(url, img_url)  # 将相对URL转换为绝对URL

        try:
            pos = img_url.index('?')
            img_url = img_url[:pos]
        except ValueError:
            pass

        if is_valid(img_url):
            urls.append(img_url)
    return urls


def download_image(url, pathname):
    '''
    下载一张图片
    '''
    if not os.path.isdir(pathname):
        os.makedirs(pathname)
    
    try:
        response = requests.get(url, stream=True)
        response.raise_for_status()  # 检查请求是否成功
    except requests.exceptions.RequestException as e:
        print(f"下载 {url} 失败: {e}")
        return

    filename = os.path.join(pathname, os.path.basename(url))

    # 检查文件是否已经存在,如果存在则跳过下载
    if os.path.exists(filename):
        print(f"文件 {filename} 已经存在,跳过下载")
        return
    
    with open(filename, 'wb') as f:
        for chunk in response.iter_content(chunk_size=1024):
            if chunk:
                f.write(chunk)
    print(f"下载 {url} 完成")


def main(url, path):
    '''
    主函数
    '''
    images = get_all_images(url)
    
    # 根据URL的域名创建文件夹
    parsed_url = urlparse(url)
    domain = parsed_url.netloc
    folder_path = os.path.join(path, domain)

    if not os.path.exists(folder_path):
        os.makedirs(folder_path)
        print(f"创建文件夹: {folder_path}")

    for img_url in images:
        try:
            download_image(img_url, folder_path)
        except Exception as e:
            print(f"下载图片 {img_url} 时发生错误: {e}")


if __name__ == "__main__":
    # 替换成你要爬取的网站URL和保存图片的根目录
    website_url = "https://www.example.com"  # 例如:"https://www.nationalgeographic.com/photography/" 
    save_path = "./images"  #  例如:"/Users/yourname/pictures/"  
    
    main(website_url, save_path)

代码详解

  1. 导入库: 导入我们需要的库,包括requestsBeautifulSouposurllib.parse
  2. is_valid(url) 函数: 检查给定的URL是否有效。这可以防止程序尝试下载无效的链接。
  3. get_all_images(url) 函数: 这个函数负责从给定的URL中提取所有图片的URL。它首先发送一个HTTP请求,然后使用Beautiful Soup解析返回的HTML内容。接着,它找到所有的<img>标签,提取src属性,并使用urljoin函数将相对URL转换为绝对URL。最后,它返回一个包含所有图片URL的列表。
  4. download_image(url, pathname) 函数: 这个函数负责下载单个图片。它首先检查保存图片的文件夹是否存在,如果不存在则创建它。然后,它发送一个HTTP请求下载图片,并将图片保存到指定的文件夹中。为了防止程序崩溃,我们使用了try...except块来捕获可能发生的异常。
  5. main(url, path) 函数: 这是主函数,它协调整个爬虫的工作。它首先调用get_all_images函数获取所有图片的URL。然后,它遍历这些URL,并调用download_image函数下载每个图片。为了更好地组织图片,它会根据URL的域名创建文件夹,并将图片保存到对应的文件夹中。
  6. if __name__ == "__main__":: 这是Python的入口点,它确保我们的代码只在直接运行脚本时执行,而不是在被作为模块导入时执行。在这里,我们指定要爬取的网站URL和保存图片的根目录,并调用main函数开始爬取。

如何使用

  1. 替换URL: 将代码中的website_url替换成你想要爬取的网站URL。
  2. 替换保存路径: 将代码中的save_path替换成你想要保存图片的根目录。
  3. 运行代码: 在命令行中运行Python脚本:python your_script_name.py

进阶技巧

  • 自定义文件夹分类: 你可以根据自己的需求修改main函数,实现更复杂的文件夹分类逻辑。例如,你可以根据图片的标签、大小、类型等信息进行分类。
  • 处理动态加载的内容: 如果网站使用JavaScript动态加载图片,你需要使用Selenium等工具来模拟浏览器行为,获取完整的HTML内容。
  • 设置请求头: 有些网站会检查请求头,你可以设置User-Agent等请求头来模拟浏览器,避免被网站屏蔽。
  • 添加延时: 为了避免给网站服务器带来过大的压力,你可以在每次请求之间添加延时。
  • 使用代理: 如果你的IP地址被网站屏蔽,你可以使用代理IP地址来继续爬取。

注意事项

  • 遵守robots.txt协议: 在爬取网站之前,请务必查看网站的robots.txt文件,了解网站允许哪些内容被爬取,哪些内容禁止爬取。
  • 尊重网站的版权: 爬取到的图片可能受到版权保护,请勿用于商业用途。
  • 不要过度爬取: 过度爬取可能会给网站服务器带来过大的压力,甚至导致网站崩溃。请合理控制爬取速度和频率。

总结

通过这个教程,你已经学会了如何使用Python编写一个简单的爬虫,从网站上抓取图片并按照文件夹分类保存。希望你能将这些知识应用到实际项目中,创造出更多有趣的应用!记住,爬虫技术是一把双刃剑,请务必遵守法律法规和网站的规则,做一个负责任的爬虫工程师!

点评评价

captcha
健康