You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过Python正确批量下载共享Google Drive中的图片?(解决403 Forbidden及文件过小问题)

解决Google Drive共享图片批量下载的403 Forbidden与不完整文件问题

你的问题其实是Google Drive的反爬限制和权限验证逻辑导致的:

  • 403错误:频繁无间隔的请求会触发Google的反爬虫机制,直接被拦截;另外共享文件如果没有设置为「任何人可查看」,也会返回权限不足的403。
  • 1KB空文件:这不是真正的图片,而是Google返回的人机验证跳转页面,shutil直接保存了这个页面内容,而非实际图片。

下面是经过验证的解决方案,用requests库替代wget/urllib,配合会话管理、请求头模拟和延迟策略来规避限制:

完整代码示例

import requests
import time
import pandas as pd
import os

# 目标保存文件夹,先创建好
save_dir = "downloaded_pics"
os.makedirs(save_dir, exist_ok=True)

# 模拟浏览器请求头,避免被识别为爬虫
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

# 创建会话,保持连接状态
session = requests.Session()
session.headers.update(headers)

for idx, pic_id in enumerate(profile_links_df['id_pic']):
    try:
        # 构建Google Drive直接下载链接
        base_url = "https://docs.google.com/uc?export=download&id="
        download_url = base_url + pic_id
        file_name = f"id_pic{idx}.png"
        save_path = os.path.join(save_dir, file_name)

        # 发送请求,允许重定向
        response = session.get(download_url, allow_redirects=True)
        response.raise_for_status()  # 抛出HTTP错误

        # 检查是否需要处理Google的验证页面(针对大文件或权限验证)
        if "confirm" in response.url:
            # 提取验证token
            confirm_token = response.url.split("confirm=")[1].split("&")[0]
            # 重新构建带验证的下载链接
            verified_url = f"{download_url}&confirm={confirm_token}"
            response = session.get(verified_url, allow_redirects=True)
            response.raise_for_status()

        # 保存图片文件
        with open(save_path, "wb") as f:
            f.write(response.content)
        
        print(f"成功下载: {file_name}")
        # 添加随机延迟,避免请求过于频繁,降低被封风险
        time.sleep(1.5 + (idx % 2))  # 1.5-2.5秒的随机间隔

    except Exception as e:
        print(f"下载失败(ID: {pic_id}): {str(e)}")
        # 可以在这里记录错误ID到日志文件,后续手动处理
        with open("download_errors.log", "a", encoding="utf-8") as log:
            log.write(f"{idx},{pic_id},{str(e)}\n")
        # 遇到错误后稍长一点的延迟,避免连续触发限制
        time.sleep(3)

关键优化点说明

  • 会话管理:用requests.Session()保持连接,减少重复建立连接的开销,同时更贴近浏览器的请求模式。
  • 请求头模拟:添加User-Agent伪装成浏览器,避免被Google直接识别为爬虫。
  • 验证页面处理:当Google要求验证时,自动提取验证token并重新请求,解决1KB空文件问题。
  • 请求延迟:每次请求后添加1.5-2.5秒的延迟,错误后延长到3秒,降低触发反爬限制的概率。
  • 异常处理:捕获请求错误并记录,避免单个失败导致整个循环中断。

前置检查

在运行代码前,请确认:

  • 共享的Google Drive图片已设置为「任何人有链接均可查看」的权限,否则即使代码正确也会返回权限错误。
  • 你的网络环境可以正常访问Google Drive,必要时检查代理设置。

内容的提问来源于stack exchange,提问作者mitrik_bnr

火山引擎 最新活动