Python中scrapy FilesPipeline下载视频文件的问题

使用 scrapy 抓取的视频 url,有过期时间,本来自定义在 pipline 写了一个使用 requests 下载( stream=True ),但是发现 scrapy 自带的有下载视频文件。不知道这个下载是否可靠。有大佬用吗。
Python中scrapy FilesPipeline下载视频文件的问题

5 回复

python 下载视频文件,一般都是用什么工具啊。是用的 requests 吗。


我经常用Scrapy的FilesPipeline下载视频,遇到问题主要是这几个点:

1. 视频文件太大导致超时

# 在settings.py中调整下载超时和大小限制
FILES_STORE = './videos'
FILES_URLS_FIELD = 'file_urls'
FILES_RESULT_FIELD = 'files'

# 关键配置
DOWNLOAD_TIMEOUT = 3600  # 1小时超时
DOWNLOAD_MAXSIZE = 1073741824  # 1GB限制
DOWNLOAD_WARNSIZE = 536870912  # 512MB警告
CONCURRENT_REQUESTS = 1  # 视频下载建议串行
CONCURRENT_REQUESTS_PER_DOMAIN = 1

2. 视频URL需要特殊处理

import scrapy
from scrapy.pipelines.files import FilesPipeline
from urllib.parse import urlparse

class VideoPipeline(FilesPipeline):
    def get_media_requests(self, item, info):
        # 处理需要referer或cookies的视频
        headers = {
            'Referer': item.get('referer', ''),
            'User-Agent': 'Mozilla/5.0...'
        }
        for url in item.get(self.files_urls_field, []):
            yield scrapy.Request(url, headers=headers, meta={'item': item})
    
    def file_path(self, request, response=None, info=None, *, item=None):
        # 自定义文件名,避免重复
        url = request.url
        parsed = urlparse(url)
        filename = parsed.path.split('/')[-1] or f"video_{hash(url)}.mp4"
        return f"videos/{filename}"

3. 处理分片视频(m3u8)

# 需要额外处理m3u8格式
import m3u8
import requests
from scrapy import Item, Field

class VideoItem(Item):
    m3u8_url = Field()
    video_urls = Field()  # 存储解析后的ts片段

# 在spider中解析m3u8
def parse_m3u8(self, response):
    playlist = m3u8.loads(response.text)
    ts_urls = [urljoin(response.url, seg.uri) 
               for seg in playlist.segments]
    yield VideoItem(video_urls=ts_urls)

4. 常见问题解决

  • 403错误:加headers,特别是Referer
  • 下载不完整:检查超时设置,大文件要用流式下载
  • 文件名重复:重写file_path方法
  • 内存溢出:降低并发数,使用CONCURRENT_REQUESTS=1

总结:视频下载主要注意超时、并发和请求头设置。

scrapy FilesPipeline

应该把“视频文件”换成“二进制流”来理解,实际上只要是个 HTTP 客户端库都可以,并没有什么可不可靠的问题。

看了一下 scrapy 的文档,FilesPipeline 完全没问题,用就完事了

回到顶部