如何在依赖scrapy-splash的Docker镜像/容器中运行多个Python脚本?
如何在Docker中同时运行你的Scrapy脚本和Scrapy-Splash服务
我来帮你搞定这个问题——在Docker里运行依赖Scrapy-Splash的Python脚本,最优雅的方式是用Docker Compose把两个服务(你的Scrapy应用和Splash服务)编排在一起,这样它们能无缝通信,部署到VPS也很方便。下面是一步步的具体操作:
方案一:Docker Compose 编排(推荐)
这种方式把你的Scrapy代码和Splash服务分成两个独立容器,各自维护,扩展性和可维护性都更好。
1. 整理你的项目结构
先把你的文件整理成这样的目录结构(假设你的Scrapy项目叫my_scrapy_spider):
my_scrapy_spider/ ├── Dockerfile # 你的Python应用镜像配置 ├── docker-compose.yml # 容器编排配置 ├── requirements.txt # Python依赖列表 └── your_spider_files/ # 你的所有.py爬虫文件和Scrapy项目文件 ├── scrapy.cfg └── my_spider/ ├── settings.py ├── spiders/ │ └── your_spider.py └── ...
2. 编写Dockerfile(构建你的Scrapy应用镜像)
创建Dockerfile,基于Python镜像安装所需依赖:
# 使用官方Python镜像作为基础 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 复制依赖文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制你的所有爬虫代码到容器中 COPY your_spider_files/ . # 启动命令(可以根据需要修改,比如直接运行指定爬虫) CMD ["scrapy", "crawl", "your_spider_name"]
3. 编写requirements.txt
把你的Python依赖列出来,至少包含:
scrapy scrapy-splash
4. 配置Scrapy的settings.py
修改你的Scrapy项目settings.py,把Splash服务的地址指向Docker Compose里的Splash服务名(因为Docker内部网络会把服务名解析成对应容器的IP):
# 启用Splash中间件 DOWNLOADER_MIDDLEWARES = { 'scrapy_splash.SplashCookiesMiddleware': 723, 'scrapy_splash.SplashMiddleware': 725, 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810, } # 设置Splash服务地址(这里的`splash`是docker-compose里的服务名) SPLASH_URL = 'http://splash:8050' # 启用Splash的DUPEFILTER DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter' HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
5. 编写docker-compose.yml(编排两个服务)
创建docker-compose.yml,定义你的Scrapy应用和Splash服务:
version: '3.8' services: # Splash服务 splash: image: scrapinghub/splash:latest ports: - "8050:8050" # 可选:如果需要从VPS外部访问Splash调试的话打开,部署时可以注释 restart: unless-stopped # 你的Scrapy应用服务 my_scrapy_app: build: . depends_on: - splash # 告诉Compose先启动Splash再启动你的应用 restart: unless-stopped # 可选:如果你的爬虫需要输出文件到本地,可以挂载目录 # volumes: # - ./output:/app/output
6. 部署到VPS并运行
- 把整个项目文件夹上传到你的VPS(比如用
scp或者Git) - 在VPS上安装Docker和Docker Compose(如果还没装的话)
- 进入项目目录,运行命令:
# 构建镜像并后台运行服务 docker-compose up --build -d - 查看日志确认运行正常:
docker-compose logs -f my_scrapy_app
方案二:将Splash集成到单个镜像(不推荐)
如果你非要把Splash和你的代码打包到一个镜像里,也可以这么做,但维护起来比较麻烦(Splash依赖很多系统库,镜像会很大)。简单说下思路:
- 基于
scrapinghub/splash镜像作为基础 - 在上面安装Python和你的依赖
- 复制代码到容器
- 启动时同时启动Splash服务和你的爬虫脚本(需要用
supervisord或者类似工具管理多个进程)
这种方式不如Docker Compose灵活,所以除非有特殊需求,否则优先选方案一。
注意事项
- 如果你不需要从外部访问Splash,docker-compose里的
ports可以删掉,这样更安全 - 如果你的爬虫启动太快,Splash还没准备好,可以在你的启动命令里加个等待,比如用
wait-for-it工具:
在Dockerfile里安装wait-for-it,然后修改CMD为:CMD ["wait-for-it", "splash:8050", "--", "scrapy", "crawl", "your_spider_name"] - VPS上要确保防火墙打开了必要的端口(如果映射了8050的话),或者直接用内部网络通信不需要开端口
内容的提问来源于stack exchange,提问作者user7956701




