You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Heroku上用ChromeDriver将截图保存到Django的CloudinaryField?

解决Heroku上Django+ChromeDriver截图保存到CloudinaryField的问题

1. 先解决截图未生成的问题

Heroku采用临时文件系统,/app目录虽存在,但直接写入固定文件名可能因权限或临时存储机制导致文件无法保留。建议使用Heroku官方推荐的可写临时目录/tmp,该目录是每个dyno的专属临时存储,读写权限更可靠:

# 替换原截图路径为/tmp目录
driver.save_screenshot('/tmp/a.png')

2. 正确将截图上传到CloudinaryField

你当前直接传递本地文件路径给CloudinaryField的写法错误——Cloudinary无法访问Heroku本地临时路径,必须传递文件对象才能完成上传。修改代码如下:

screenshot_path = '/tmp/a.png'
# 确认截图成功生成后再处理
if driver.save_screenshot(screenshot_path):
    # 以二进制模式打开截图文件
    with open(screenshot_path, 'rb') as img_file:
        # 将文件对象传入CloudinaryField
        UploadedImage.objects.create(image=img_file)
else:
    return HttpResponse("截图生成失败", status=500)

3. 其他关键优化

  • ChromeDriver路径管理:在Heroku上建议通过heroku-buildpack-chromedriver构建包管理ChromeDriver,可通过环境变量自动获取路径,避免手动指定出错:
    import os
    driver_path = os.environ.get('CHROMEDRIVER_PATH', '/app/.chromedriver/bin/chromedriver')
    driver = webdriver.Chrome(executable_path=driver_path, options=options)
    
  • 资源清理:使用完ChromeDriver后必须调用quit()关闭,避免内存泄漏:
    driver.quit()
    
  • Cloudinary配置检查:确保Django的settings.py已通过环境变量配置好Cloudinary参数(如CLOUDINARY_URL),这是Heroku上Cloudinary正常工作的前提。

完整修正后的视图片段

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from django.http import HttpResponse
from .models import UploadedImage
import os

def capture_weather_screenshot(request):
    options = Options()
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-extensions')
    options.add_argument('--proxy-server="direct://"')
    options.add_argument('--proxy-bypass-list=*')
    options.add_argument('--start-maximized')
    options.add_argument('--headless')
    options.add_argument('--no-sandbox')
    
    driver_path = os.environ.get('CHROMEDRIVER_PATH', '/app/.chromedriver/bin/chromedriver')
    driver = webdriver.Chrome(executable_path=driver_path, options=options)
    
    try:
        driver.get('https://weather.yahoo.co.jp/weather/')
        driver.set_window_size(1250, 1036)
        screenshot_path = '/tmp/a.png'
        
        if driver.save_screenshot(screenshot_path):
            with open(screenshot_path, 'rb') as img_file:
                UploadedImage.objects.create(image=img_file)
            return HttpResponse("Success")
        else:
            return HttpResponse("截图生成失败", status=500)
    finally:
        driver.quit()

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:36:26