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

如何仅用Python标准库实现.doc文件指定关键词搜索?

针对.doc文件的轻量关键词搜索方案(仅用Python标准库)

核心思路

.doc属于OLE复合文档格式,无法像docx那样通过解压读取XML内容。我们可以直接解析二进制结构,提取其中的WordDocument核心流,过滤出可识别的文本片段后匹配关键词,全程依赖Python标准库实现。

实现代码

import os
import re
import struct
import logger

def doc_file(root: str, file: str, keywords: list) -> list:
    hits = []
    file_path = os.path.join(root, file)
    try:
        with open(file_path, 'rb') as f:
            # 验证是否为合法OLE复合文档
            header = f.read(8)
            if header != b'\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1':
                logger.warning(f"{file} is not a valid .doc file")
                return hits
            
            # 读取目录条目数量,定位目录区
            f.seek(0x30)
            dir_entry_count = struct.unpack('<I', f.read(4))[0]
            f.seek(0x40)
            
            # 遍历目录条目,找到WordDocument流
            word_stream_info = None
            for _ in range(dir_entry_count):
                entry = f.read(128)
                name = entry[:64].decode('utf-16le').rstrip('\x00')
                stream_size = struct.unpack('<Q', entry[0x70:0x78])[0]
                stream_start_sec = struct.unpack('<I', entry[0x78:0x7C])[0]
                if name == 'WordDocument':
                    word_stream_info = (stream_size, stream_start_sec)
                    break
            
            if not word_stream_info:
                logger.warning(f"No WordDocument stream found in {file}")
                return hits
            
            # 获取扇区大小,定位到流起始位置
            f.seek(0x18)
            sector_size = 1 << struct.unpack('<H', f.read(2))[0]
            f.seek(sector_size * word_stream_info[1])
            stream_data = f.read(word_stream_info[0])
            
            # 过滤出可打印文本(剔除控制字符和非ASCII乱码)
            text = ''.join([chr(b) for b in stream_data if 32 <= b <= 126 or b in [9, 10, 13]])
            
            # 匹配关键词
            for keyword in keywords:
                if re.search(keyword, text):
                    hits.append(keyword)
                    
    except Exception as e:
        logger.warning(f"Failed to process {file}: {str(e)}")
        return hits
    
    return hits

说明

  • 直接操作二进制文件解析OLE结构,仅提取核心的文本承载流,避免复杂格式解析
  • 通过过滤非打印字符,保留可识别的文本片段用于关键词匹配
  • 完全依赖Python标准库,无需额外安装第三方包
  • 局限性:无法还原所有格式化文本,可能遗漏部分隐藏内容,但满足基础关键词搜索需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:50:20