Python实用工具:textract 一站式多格式文档文本提取教程

一、textract库核心概述

1.1 功能用途

textract是一款面向Python开发者的多格式文档文本提取工具,能够自动解析并提取数十种常见文件格式中的文本内容,涵盖文档类(DOC、DOCX、PDF、TXT)、表格类(XLS、XLSX、CSV)、演示类(PPT、PPTX)、压缩包类(ZIP、RAR)等主流格式,无需开发者手动编写不同格式的解析逻辑,极大降低了跨格式文本提取的开发门槛。

1.2 工作原理

textract的核心工作逻辑是封装第三方格式解析工具与库,通过调用不同的底层依赖来处理对应格式的文件:对于PDF文件,会调用pdfminerpdftotext;对于Office文档,依赖python-docxxlrdpython-pptx等库;对于压缩包,会先解压再提取内部文件文本。工具会自动识别输入文件的格式,匹配对应的解析器,最终将提取的文本整合为统一的字符串输出。

1.3 优缺点分析

优点

  • 格式支持全面,一站式解决多类型文件的文本提取需求;
  • 调用接口简洁,一行代码即可完成文本提取;
  • 兼容Python 3.x版本,适配主流开发环境。

缺点

  • 底层依赖较多,安装时需要配置各类第三方工具,部分格式(如加密PDF)无法处理;
  • 大文件提取速度较慢,内存占用较高;
  • 对部分小众格式的支持不够完善,存在解析失败的情况。

1.4 License类型

textract采用MIT开源许可证,开发者可以自由使用、修改和分发代码,无论是个人项目还是商业项目都无需支付授权费用,仅需保留原作者的版权声明。

二、textract库安装指南

2.1 系统依赖准备

由于textract依赖大量第三方工具,不同操作系统的安装步骤存在差异,需先配置系统级依赖:

2.1.1 Windows系统

Windows用户需要安装以下工具,并确保其添加到系统环境变量中:

  • poppler:用于PDF文件解析,下载地址:http://blog.alivate.com.au/poppler-windows/
  • antiword:用于DOC文件解析,下载地址:https://www.winfield.demon.nl/
  • unrar:用于RAR压缩包解析,下载地址:https://www.rarlab.com/rar_add.htm

下载后解压到指定目录,例如C:\Tools,并将对应工具的可执行文件路径(如C:\Tools\poppler-23.11.0\Library\bin)添加到系统环境变量Path中。

2.1.2 Linux系统

Linux用户可通过包管理器直接安装所有依赖,以Ubuntu/Debian为例:

sudo apt-get update
sudo apt-get install python3-dev python3-pip antiword unrtf poppler-utils pstotext tesseract-ocr flac ffmpeg lame libmad0 libsox-fmt-mp3 sox libjpeg-dev swig

以CentOS/RHEL为例:

sudo yum install python3-devel python3-pip antiword unrtf poppler-utils tesseract flac ffmpeg lame libmad sox libjpeg-turbo-devel swig

2.1.3 macOS系统

macOS用户可通过Homebrew安装依赖:

brew install python3 antiword unrtf poppler tesseract flac ffmpeg lame sox

2.2 Python包安装

完成系统依赖配置后,通过pip命令安装textract库:

pip install textract

验证安装是否成功,在Python交互式环境中执行以下代码:

import textract
print(textract.__version__)

若输出对应的版本号(如1.6.5),则说明安装成功。若出现导入错误,需检查系统依赖是否配置正确,或重新安装对应缺失的工具。

三、textract库核心API使用教程

3.1 基础文本提取:extract函数

textract的核心功能由textract.process()函数实现,该函数接收文件路径作为参数,自动识别文件格式并返回提取的文本内容(字节串格式)。

3.1.1 提取TXT文件文本

TXT文件是最基础的文本格式,textract提取过程无需额外依赖,代码示例如下:

# 导入textract库
import textract

# 定义TXT文件路径
txt_file_path = "example.txt"

# 提取文本内容,返回字节串
text_bytes = textract.process(txt_file_path)

# 将字节串解码为字符串
text_str = text_bytes.decode("utf-8")

# 打印提取的文本
print("提取的TXT文件内容:")
print(text_str)

代码说明textract.process()函数读取example.txt文件,返回UTF-8编码的字节串,通过decode("utf-8")转换为可阅读的字符串。若TXT文件采用其他编码(如GBK),需在decode时指定对应的编码格式。

3.1.2 提取PDF文件文本

PDF文件是办公场景中最常用的格式之一,textract依赖poppler工具解析PDF,代码示例如下:

import textract

# 定义PDF文件路径
pdf_file_path = "example.pdf"

# 提取PDF文本,指定编码为utf-8
try:
    text_bytes = textract.process(
        pdf_file_path,
        encoding="utf-8"
    )
    text_str = text_bytes.decode("utf-8")
    print("提取的PDF文件内容:")
    print(text_str)
except Exception as e:
    print(f"PDF提取失败:{e}")

代码说明:使用try-except捕获可能的异常(如文件不存在、依赖缺失),避免程序崩溃。对于扫描版PDF(图片格式),textract无法直接提取文本,需结合OCR工具(如tesseract)进行处理,后续会介绍对应的方法。

3.1.3 提取Word文档文本

Word文档分为.doc.docx两种格式,textract分别依赖antiword和python-docx库处理,代码示例如下:

import textract

# 提取.doc格式文档
doc_file_path = "example.doc"
try:
    doc_text = textract.process(doc_file_path).decode("utf-8")
    print("提取的DOC文件内容:")
    print(doc_text)
except Exception as e:
    print(f"DOC提取失败:{e}")

# 提取.docx格式文档
docx_file_path = "example.docx"
try:
    docx_text = textract.process(docx_file_path).decode("utf-8")
    print("\n提取的DOCX文件内容:")
    print(docx_text)
except Exception as e:
    print(f"DOCX提取失败:{e}")

代码说明.doc.docx格式的提取代码完全一致,textract会自动识别文件后缀并调用对应的解析器。需要注意的是,antiword工具对部分复杂格式的.doc文件支持不够完善,可能出现文本乱码的情况。

3.1.4 提取Excel表格文本

Excel表格(.xls.xlsx)的文本提取会将所有单元格的内容按行拼接,代码示例如下:

import textract

# 提取xlsx格式表格
xlsx_file_path = "example.xlsx"
try:
    xlsx_text = textract.process(xlsx_file_path).decode("utf-8")
    # 按换行符分割每行内容
    rows = xlsx_text.split("\n")
    print("Excel表格提取的内容(按行显示):")
    for index, row in enumerate(rows):
        if row.strip():  # 跳过空行
            print(f"第{index+1}行:{row.strip()}")
except Exception as e:
    print(f"Excel提取失败:{e}")

代码说明:提取的Excel文本中,不同行之间用换行符分隔,同一行的不同单元格内容用制表符或空格分隔。通过split("\n")可以将文本按行拆分,方便后续处理。

3.2 进阶功能:指定解析器与参数

textract允许开发者手动指定解析器,以覆盖自动识别的逻辑,同时支持传递额外参数优化提取效果。

3.2.1 手动指定解析器

以PDF文件为例,textract支持pdfminerpdftotext两种解析器,可通过method参数指定:

import textract

pdf_file_path = "example.pdf"

# 使用pdftotext解析器提取PDF文本
try:
    text = textract.process(
        pdf_file_path,
        method="pdftotext",  # 指定解析器
        encoding="utf-8"
    ).decode("utf-8")
    print("使用pdftotext提取的PDF内容:")
    print(text)
except Exception as e:
    print(f"解析失败:{e}")

代码说明method参数的值需与textract支持的解析器名称一致,不同格式对应的解析器可参考官方文档。手动指定解析器可以解决自动识别失败的问题,提升提取成功率。

3.2.2 处理扫描版PDF(OCR识别)

扫描版PDF本质是图片集合,需要结合OCR工具提取文本。textract支持调用tesseract-ocr进行OCR识别,代码示例如下:

import textract

# 扫描版PDF文件路径
scan_pdf_path = "scan_example.pdf"

# 使用OCR提取文本,指定语言为中文
try:
    ocr_text = textract.process(
        scan_pdf_path,
        method="tesseract",
        language="chi_sim"  # chi_sim表示简体中文,eng表示英文
    ).decode("utf-8")
    print("扫描版PDF的OCR识别结果:")
    print(ocr_text)
except Exception as e:
    print(f"OCR识别失败:{e}")

代码说明:使用method="tesseract"指定OCR解析器,language参数设置识别语言(需提前安装对应的语言包)。tesseract默认支持英文,若需识别中文,需下载简体中文语言包并放置到tesseract的tessdata目录下。

3.2.3 提取压缩包内文件文本

textract支持直接提取ZIP、RAR等压缩包内的所有文件文本,无需手动解压,代码示例如下:

import textract

# ZIP压缩包路径
zip_file_path = "example.zip"

try:
    # 提取压缩包内所有文件的文本
    zip_text = textract.process(zip_file_path).decode("utf-8")
    print("压缩包内文件的文本内容:")
    print(zip_text)
except Exception as e:
    print(f"压缩包提取失败:{e}")

代码说明:textract会自动解压压缩包,遍历内部所有文件并提取文本,最终将所有内容拼接为一个字符串。若压缩包内包含加密文件,提取会失败。

3.3 错误处理与最佳实践

3.3.1 常见异常类型及处理

在使用textract的过程中,常见的异常包括文件不存在依赖缺失格式不支持权限不足等,开发者需针对性地进行处理:

import textract
import os

def extract_file_text(file_path):
    """
    通用文本提取函数,包含异常处理
    :param file_path: 文件路径
    :return: 提取的文本字符串,失败返回None
    """
    # 检查文件是否存在
    if not os.path.exists(file_path):
        print(f"错误:文件 {file_path} 不存在")
        return None
    # 检查文件权限
    if not os.access(file_path, os.R_OK):
        print(f"错误:没有读取文件 {file_path} 的权限")
        return None
    try:
        text_bytes = textract.process(file_path)
        return text_bytes.decode("utf-8", errors="ignore")  # 忽略解码错误
    except textract.exceptions.ExtensionNotSupported as e:
        print(f"错误:不支持的文件格式 - {e}")
        return None
    except textract.exceptions.ShellError as e:
        print(f"错误:底层工具调用失败 - {e},请检查系统依赖")
        return None
    except Exception as e:
        print(f"未知错误:{e}")
        return None

# 测试函数
test_files = ["example.txt", "unknown.xyz", "example.pdf"]
for file in test_files:
    print(f"\n=== 提取 {file} 的内容 ===")
    text = extract_file_text(file)
    if text:
        print(text[:200])  # 仅打印前200个字符

代码说明:定义通用提取函数extract_file_text,先检查文件存在性和读取权限,再通过try-except捕获textract的特定异常和通用异常,确保程序的健壮性。decode时设置errors="ignore"可以忽略部分编码错误,避免因个别字符问题导致提取失败。

3.3.2 最佳实践建议

  1. 提前安装所有依赖:根据开发环境,一次性安装好所有系统级依赖和Python库,避免运行时出现工具缺失的问题;
  2. 小文件优先测试:在处理大量文件前,先用小文件测试提取效果,确认格式支持和编码设置正确;
  3. 大文件分块处理:对于超过100MB的大文件,建议分块读取或使用其他工具辅助,避免textract占用过多内存;
  4. 结合其他库优化:对于复杂格式的文件,可结合python-docxPyPDF2等库单独处理,提升提取精度;
  5. 日志记录:在生产环境中,将提取过程的异常信息记录到日志文件,方便后续排查问题。

四、实战案例:批量提取文件夹内所有文件的文本

4.1 需求描述

在实际开发中,经常需要批量提取某个文件夹内所有文件的文本内容,并将结果保存到指定的TXT文件中。本案例将实现一个批量提取工具,支持递归遍历子文件夹,自动过滤不支持的文件格式。

4.2 实现代码

import textract
import os
from pathlib import Path

def batch_extract_text(input_dir, output_file, supported_extensions=None):
    """
    批量提取文件夹内所有文件的文本
    :param input_dir: 输入文件夹路径
    :param output_file: 输出文本文件路径
    :param supported_extensions: 支持的文件后缀列表,None表示支持所有textract格式
    """
    # 默认支持的文件后缀,可根据需求扩展
    default_supported = {
        ".txt", ".pdf", ".doc", ".docx", ".xls", ".xlsx",
        ".ppt", ".pptx", ".csv", ".zip", ".rar"
    }
    if supported_extensions is None:
        supported_extensions = default_supported
    else:
        supported_extensions = set(supported_extensions)

    # 打开输出文件,使用追加模式
    with open(output_file, "w", encoding="utf-8") as f_out:
        # 递归遍历文件夹
        for root, dirs, files in os.walk(input_dir):
            for file in files:
                file_path = Path(root) / file
                file_ext = file_path.suffix.lower()
                # 过滤不支持的文件格式
                if file_ext not in supported_extensions:
                    continue
                print(f"正在提取:{file_path}")
                # 调用提取函数
                text = extract_file_text(str(file_path))
                if text:
                    # 写入文件路径和提取的文本
                    f_out.write(f"=== 文件路径:{file_path} ===\n")
                    f_out.write(text)
                    f_out.write("\n" + "="*50 + "\n\n")
                else:
                    f_out.write(f"=== 文件路径:{file_path} ===\n")
                    f_out.write("提取失败\n")
                    f_out.write("\n" + "="*50 + "\n\n")
    print(f"批量提取完成,结果已保存到:{output_file}")

# 复用之前定义的提取函数
def extract_file_text(file_path):
    if not os.path.exists(file_path):
        return None
    if not os.access(file_path, os.R_OK):
        return None
    try:
        text_bytes = textract.process(file_path)
        return text_bytes.decode("utf-8", errors="ignore")
    except Exception:
        return None

# 测试批量提取功能
if __name__ == "__main__":
    input_directory = "test_files"  # 输入文件夹
    output_txt = "batch_extract_result.txt"  # 输出文件
    batch_extract_text(input_directory, output_txt)

4.3 代码说明

  1. 函数参数说明input_dir为待处理的文件夹路径,output_file为结果保存的文件路径,supported_extensions为自定义支持的文件后缀列表;
  2. 递归遍历:使用os.walk()函数递归遍历文件夹内的所有文件,包括子文件夹中的文件;
  3. 格式过滤:通过文件后缀过滤不支持的格式,仅处理指定类型的文件;
  4. 结果保存:将每个文件的路径和提取的文本写入输出文件,用分隔符区分不同文件的内容,方便后续查看和分析。

4.4 运行步骤

  1. 创建test_files文件夹,放入各类测试文件(如TXT、PDF、Word、Excel等);
  2. 运行上述代码,程序会自动遍历test_files文件夹;
  3. 查看生成的batch_extract_result.txt文件,即可获取所有文件的文本提取结果。

五、相关资源链接

  • PyPI地址:https://pypi.org/project/textract
  • GitHub地址:https://github.com/deanmalmgren/textract
  • 官方文档地址:https://textract.readthedocs.io/en/stable/

关注我,每天分享一个实用的Python自动化工具。