Python 爬取图片攻略:告别水印,批量保存高清图片

3 阅读5分钟

在内容创作与素材收集的日常工作中,某些网站凭借海量优质图文素材,成为设计师、自媒体人、电商运营的核心素材库。但平台自带的水印、限制批量下载等问题,极大影响了素材使用效率。手动一张张保存不仅耗时费力,还无法去除水印,而借助 Python 爬虫,我们可以轻松实现无水印高清图片批量爬取,彻底解决素材收集痛点。

一、核心原理:小红书水印图片的底层逻辑

在开始编码前,我们需要先理解图片水印的实现原理,这是实现无水印爬取的关键:

  1. 水印并非图片本身属性:网站展示的带水印图片,是平台通过接口返回的加工后图片,原始无水印图片存储在独立的服务器地址中;
  2. 接口数据解密:网站前端页面不会直接暴露原始图片链接,而是通过加密接口返回笔记数据,我们需要定位到数据接口并解密;
  3. 关键参数提取:笔记详情接口中包含<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">original</font>(原始图片)字段,这就是无水印高清图片的真实地址,直接请求该地址即可获取无水印素材。

同时,网站具备基础的反爬机制,主要包括:请求头校验、Cookie 时效限制、IP 访问频率限制,我们在代码中会针对性解决这些问题。

二、环境准备:搭建爬虫开发环境

本次实战基于 Python 3.8 + 版本,需要安装三个核心依赖库,打开终端执行以下安装命令:

bash

运行

# 网络请求库,用于发送HTTP请求
pip install requests
# 解析JSON数据,处理接口返回内容
pip install json
# 文件操作与进度提示
pip install tqdm

核心库作用说明:

  • <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">requests</font>:替代浏览器发送网络请求,模拟用户访问小红书接口;
  • <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">json</font>:解析接口返回的加密 / 结构化数据,提取图片链接;
  • <font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">tqdm</font>:为批量下载添加进度条,提升使用体验。

三、关键步骤:获取请求必备参数

网站接口需要携带合法的请求头和 Cookie 才能正常访问,我们通过浏览器开发者工具获取参数:

  1. 打开电脑端小红书网页版,登录你的账号;
  2. 按下<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">F12</font>打开开发者工具,切换到Network(网络) 面板;
  3. 刷新页面,打开任意一篇笔记,在过滤栏输入<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">feed</font>,找到接口请求;
  4. 复制请求头中的CookieUser-Agent两个核心参数。

⚠️ 重要提醒:Cookie 是你的账号凭证,切勿泄露给他人,且具有时效性,失效后重新复制即可。

四、完整代码实现:无水印图片批量爬取

以下是完整可运行的代码,包含请求配置、接口解析、图片下载、批量处理四大核心模块,代码中已添加详细注释,直接替换参数即可使用。

python

运行

import requests
import os
import time
from tqdm import tqdm

class XiaohongshuImageSpider:
    def __init__(self):
        # 请求头配置(替换成自己浏览器的参数)
        self.headers = {
            "User-Agent": "这里填写你的User-Agent",
            "Cookie": "这里填写你的Cookie",
            "Referer": "https://www.xiaohongshu.com/",
        }

        # ==================== 亿牛云代理配置 ====================
        # 替换为你在亿牛云获取的代理信息
        self.proxy_host = "亿牛云代理域名"
        self.proxy_port = "端口"
        self.proxy_user = "代理账号"
        self.proxy_pwd = "代理密码"

        # 构建代理
        self.proxies = {
            "http": f"http://{self.proxy_user}:{self.proxy_pwd}@{self.proxy_host}:{self.proxy_port}",
            "https": f"http://{self.proxy_user}:{self.proxy_pwd}@{self.proxy_host}:{self.proxy_port}"
        }
        # ======================================================

        # 图片保存路径
        self.save_dir = "./无水印图片"
        if not os.path.exists(self.save_dir):
            os.mkdir(self.save_dir)

    def parse_note(self, note_url):
        """
        解析笔记,获取无水印图片链接
        """
        try:
            # 从链接提取笔记ID
            note_id = note_url.split("/")[-1].split("?")[0]
            api = f"https://edith.xiaohongshu.com/api/sns/web/v1/note/{note_id}"

            # 使用亿牛云代理发送请求
            resp = requests.get(
                api,
                headers=self.headers,
                proxies=self.proxies,
                timeout=15
            )
            data = resp.json()

            if data.get("code") != 0:
                print("接口获取失败:", data.get("message"))
                return []

            # 提取无水印原图链接
            img_urls = []
            for item in data["data"]["items"]:
                if "images" in item:
                    url = item["images"]["info_list"][0]["original"]["url"]
                    img_urls.append(url)

            return img_urls

        except Exception as e:
            print("解析出错:", e)
            return []

    def download_img(self, url, index):
        """
        下载单张无水印图片
        """
        try:
            img_resp = requests.get(
                url,
                headers=self.headers,
                proxies=self.proxies,
                timeout=20
            )
            path = os.path.join(self.save_dir, f"image_{index}.jpg")
            with open(path, "wb") as f:
                f.write(img_resp.content)
            return True
        except:
            return False

    def run(self, note_url):
        print("开始解析笔记链接...")
        img_list = self.parse_note(note_url)

        if not img_list:
            print("未获取到图片")
            return

        print(f"共获取到 {len(img_list)} 张无水印图片")
        success = 0

        for i, url in enumerate(tqdm(img_list), 1):
            if self.download_img(url, i):
                success += 1
            time.sleep(1)  # 降低请求频率

        print(f"\n下载完成!成功保存 {success} 张图片")
        print(f"保存路径:{os.path.abspath(self.save_dir)}")

if __name__ == "__main__":
    spider = XiaohongshuImageSpider()
    note_link = input("请输入笔记链接:")
    spider.run(note_link)

五、代码使用教程:三步完成爬取

步骤 1:替换核心参数

找到代码中<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">__init__</font>方法下的<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">headers</font>,将<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">Cookie</font><font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">User-Agent</font>替换为你自己浏览器获取的参数。

步骤 2:输入笔记链接

运行代码后,在终端粘贴电脑端笔记链接(示例:<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">https://www.xxx.com/xxxx/xxxx.html</font>),按下回车。

步骤 3:查看结果

程序会自动解析链接、下载图片,下载完成后,在脚本同级目录的<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">无水印图片</font>文件夹中,即可查看所有无水印高清图片。

六、反爬机制应对:保证爬虫稳定运行

网站的反爬机制是新手最容易遇到的问题,我们总结了 3 个实用解决方案:

  1. 添加请求延时:代码中<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">time.sleep(1)</font>设置 1 秒延时,避免高频请求触发 IP 限制;
  2. 定期更新 Cookie:Cookie 失效后会提示<font style="color:rgb(0, 0, 0);background-color:rgba(0, 0, 0, 0);">未登录</font>,重新在浏览器复制即可;
  3. 避免高频请求:不要短时间内爬取大量笔记,个人使用完全满足需求。

七、功能扩展:进阶优化方向

基础版本已满足日常使用,我们可以在此基础上扩展功能:

  1. 多笔记批量爬取:读取文本文件中的笔记链接列表,实现自动化爬取;
  2. 分类保存:根据笔记标题创建文件夹,自动归类不同主题的图片素材;
  3. GUI 界面:结合 PyQt 库制作可视化窗口,无需代码基础即可使用;
  4. 视频爬取:扩展代码,实现小红书无水印视频下载。