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

Python CSV模块解析返回单个字符而非字符串的问题排查

问题:csv.reader解析ffprobe CSV输出时返回单个字符列表

调用ffprobe获取CSV格式的视频流信息,打印输出符合CSV格式,但用csv.reader解析subprocess.run()返回的stdout字符串时,得到的却是单个字符组成的列表,而非预期的逗号分隔字段列表。

原代码

import os
import subprocess
import csv

for file in os.listdir("/Temp/Video"):
    if file.endswith(".mkv"):
        print(os.path.join("/Temp/Video", file))
        ps = subprocess.run(["ffprobe", "-show_streams", "-print_format", "csv",  "-i", "/Temp/Video/" + file], capture_output = True, text = True)
        
        print("------------------------------------------")
        print(ps.stdout)
        print("------------------------------------------")

        reader = csv.reader(ps.stdout)

        for row in reader:
            print(row)

        exit(0)

输出情况

实际stdout输出

stream,0,h264,H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10,High,video,[0][0][0][0],0x0000,1920,1080,1920,1080,0,0,2,1:1,16:9,yuv420p,40,unknown,unknown,unknown,unknown,left,progressive,1,true,4,N/A,24000/1001,24000/1001,1/1000,0,0.000000,N/A,N/A,N/A,N/A,8,N/A,N/A,N/A,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,eng,17936509,01:20:18.271791666,115523,10802870592,001011,MakeMKV v1.16.4 win(x64-release),2021-08-20 19:09:26,BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES SOURCE_ID,Lavc59.7.102 libx264,00:01:30.010000000
stream,1,vorbis,Vorbis,unknown,audio,[0][0][0][0],0x0000,fltp,48000,3,3.0,0,0,N/A,0/0,0/0,1/1000,0,0.000000,N/A,N/A,N/A,N/A,N/A,N/A,N/A,N/A,3314,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,eng,Surround 3.0,2422660,01:20:18.272000000,451713,1459129736,001100,MakeMKV v1.16.4 win(x64-release),2021-08-20 19:09:26,BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES SOURCE_ID,Lavc59.7.102 libvorbis,00:01:30.003000000

异常解析结果

['s']
['t']
['r']
['e']
['a']
['m']
['', '']
['0']
['', '']
['h']
['2']
['6']
['4']
...

预期结果

['stream', '0', 'h264', 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10', ...]
['stream', '1', 'vorbis', 'Vorbis', 'unknown', 'audio', ...]

原因

csv.reader()要求参数是按行迭代的对象(比如文件对象、每行字符串组成的列表)。直接传入ps.stdout字符串时,Python会把字符串当作字符序列迭代——每个字符被视为一行,csv.reader解析这单个字符的"行",自然返回只有单个字符的列表。

解决方案

有两种常见修复方式:

方式1:用splitlines()分割字符串为行列表

将ps.stdout拆分成每行字符串的列表,再传给csv.reader:

reader = csv.reader(ps.stdout.splitlines())

方式2:用io.StringIO包装为类文件对象

把字符串转换成类似文件的可迭代对象,更贴合csv.reader的设计场景:

import io
reader = csv.reader(io.StringIO(ps.stdout))

修改后的完整代码

import os
import subprocess
import csv
import io

for file in os.listdir("/Temp/Video"):
    if file.endswith(".mkv"):
        file_path = os.path.join("/Temp/Video", file)
        print(file_path)
        ps = subprocess.run(
            ["ffprobe", "-show_streams", "-print_format", "csv", "-i", file_path],
            capture_output=True,
            text=True
        )
        
        print("------------------------------------------")
        print(ps.stdout)
        print("------------------------------------------")

        # 选择其中一种方式即可
        # reader = csv.reader(ps.stdout.splitlines())
        reader = csv.reader(io.StringIO(ps.stdout))

        for row in reader:
            print(row)

        exit(0)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:20:40