本文目录导读:

我来为您提供一个批量提取文件摘要信息的Python脚本,支持多种文件格式(文本、PDF、Word、Excel等)。
完整脚本
#!/usr/bin/env python3
"""信息提取工具
支持格式: .txt, .pdf, .docx, .xlsx, .csv, .md, .json, .html 等
"""
import os
import json
import hashlib
import csv
from datetime import datetime
from pathlib import Path
import argparse
import logging
from typing import Dict, List, Any
# 第三方库(需要安装)
try:
import PyPDF2
from docx import Document
import openpyxl
from PIL import Image
import mimetypes
except ImportError as e:
print(f"缺少必要库: {e}")
print("请运行: pip install PyPDF2 python-docx openpyxl pillow")
exit(1)
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('file_extractor.log', encoding='utf-8'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
class FileInfoExtractor:
"""文件信息提取器"""
def __init__(self, file_path: str):
self.file_path = Path(file_path)
self.info = {}
def extract_basic_info(self):
"""提取基本信息"""
stat = self.file_path.stat()
self.info = {
'文件名': self.file_path.name,
'文件路径': str(self.file_path),
'文件大小': f"{stat.st_size / 1024:.2f} KB",
'创建时间': datetime.fromtimestamp(stat.st_ctime).strftime('%Y-%m-%d %H:%M:%S'),
'修改时间': datetime.fromtimestamp(stat.st_mtime).strftime('%Y-%m-%d %H:%M:%S'),
'访问时间': datetime.fromtimestamp(stat.st_atime).strftime('%Y-%m-%d %H:%M:%S'),
'文件类型': self.file_path.suffix.lower(),
'MIME类型': mimetypes.guess_type(str(self.file_path))[0] or '未知',
}
# 计算MD5哈希
try:
with open(self.file_path, 'rb') as f:
file_hash = hashlib.md5()
chunk = f.read(8192)
while chunk:
file_hash.update(chunk)
chunk = f.read(8192)
self.info['MD5哈希'] = file_hash.hexdigest()
except Exception as e:
logger.warning(f"计算MD5失败: {e}")
self.info['MD5哈希'] = '计算失败'
# 权限信息
try:
mode = stat.st_mode
self.info['权限'] = oct(mode & 0o777)
except:
self.info['权限'] = '未知'
return self.info
def extract_text_info(self):
"""提取文本文件信息"""
try:
with open(self.file_path, 'r', encoding='utf-8') as f:
content = f.read()
lines = content.split('\n')
# 统计信息
self.info['行数'] = len(lines)
self.info['字符数'] = len(content)
self.info['单词数'] = len(content.split())
# 提取前几行
preview_lines = lines[:10] # 前10行预览
self.info['内容预览'] = preview_lines
# 查找关键信息(简单关键词提取)
keywords = ['作者', '标题', '日期', '版本']
found_keywords = {}
for kw in keywords:
for line in lines[:20]: # 只检查前20行
if kw in line.lower():
found_keywords[kw] = line.strip()
break
if found_keywords:
self.info['关键信息'] = found_keywords
except Exception as e:
logger.error(f"读取文本文件失败: {e}")
self.info['文本内容'] = f'读取失败: {e}'
return self.info
def extract_pdf_info(self):
"""提取PDF文件信息"""
try:
with open(self.file_path, 'rb') as f:
reader = PyPDF2.PdfReader(f)
# 基本信息
self.info['页数'] = len(reader.pages)
# 元数据
meta = reader.metadata
if meta:
self.info['PDF标题'] = meta.title if meta.title else '无'
self.info['PDF作者'] = meta.author if meta.author else '未知'
self.info['PDF主题'] = meta.subject if meta.subject else '无'
self.info['PDF创建者'] = meta.creator if meta.creator else '未知'
# 提取第一页部分文本
if len(reader.pages) > 0:
page = reader.pages[0]
text = page.extract_text()
if text:
preview = text[:300]
self.info['首页内容'] = preview.replace('\n', ' ')
except Exception as e:
logger.error(f"PDF处理失败: {e}")
self.info['PDF信息'] = f'读取失败: {e}'
return self.info
def extract_docx_info(self):
"""提取Word文档信息"""
try:
doc = Document(str(self.file_path))
# 段落数
self.info['段落数'] = len(doc.paragraphs)
self.info['节数'] = len(doc.sections)
# 表格数
self.info['表格数'] = len(doc.tables)
# 统计单词
word_count = 0
for para in doc.paragraphs:
word_count += len(para.text.split())
self.info['单词数'] = word_count
# 提取前几段
preview_paras = []
for i, para in enumerate(doc.paragraphs[:5]):
if para.text.strip():
preview_paras.append(para.text.strip())
self.info['内容预览'] = preview_paras
# 内建属性
props = doc.core_properties
self.info['文档作者'] = props.author if props.author else '未知'
self.info['创建时间'] = props.created if props.created else '未知'
self.info['修改时间'] = props.modified if props.modified else '未知'
except Exception as e:
logger.error(f"Word文档处理失败: {e}")
self.info['Word信息'] = f'读取失败: {e}'
return self.info
def extract_xlsx_info(self):
"""提取Excel表格信息"""
try:
wb = openpyxl.load_workbook(str(self.file_path), read_only=True)
# 工作表信息
sheet_names = wb.sheetnames
self.info['工作表数量'] = len(sheet_names)
self.info['工作表名称'] = sheet_names
# 每个工作表的信息
sheet_info = {}
for sheet_name in sheet_names:
ws = wb[sheet_name]
sheet_info[sheet_name] = {
'行数': ws.max_row,
'列数': ws.max_column,
'数据范围': f"A1:{ws.max_column_letter}{ws.max_row}"
}
# 获取前几行数据
preview_data = []
for row in ws.iter_rows(max_row=3, values_only=True):
preview_data.append(list(row))
sheet_info[sheet_name]['预览数据'] = preview_data
self.info['工作表详情'] = sheet_info
wb.close()
except Exception as e:
logger.error(f"Excel处理失败: {e}")
self.info['Excel信息'] = f'读取失败: {e}'
return self.info
def extract_image_info(self):
"""提取图片信息"""
try:
with Image.open(str(self.file_path)) as img:
self.info['图片格式'] = img.format
self.info['图片尺寸'] = img.size
self.info['图片模式'] = img.mode
# 图像属性
self.info['宽度'] = img.width
self.info['高度'] = img.height
# 获取EXIF信息(如果有)
try:
exif_data = img._getexif()
if exif_data:
# 常见的EXIF标签
exif_labels = {
271: '厂商', 272: '型号', 306: '拍摄时间',
34855: 'ISO', 33434: '曝光时间', 37386: '焦距'
}
exif_info = {}
for tag_id, label in exif_labels.items():
if tag_id in exif_data:
value = exif_data[tag_id]
if tag_id == 33434: # 曝光时间特殊处理
value = f"1/{int(1/float(value))}" if value else f"{value}"
exif_info[label] = value
if exif_info:
self.info['EXIF信息'] = exif_info
except:
pass # 无EXIF信息
except Exception as e:
logger.error(f"图片处理失败: {e}")
self.info['图片信息'] = f'读取失败: {e}'
return self.info
def extract_json_info(self):
"""提取JSON文件信息"""
try:
with open(self.file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
self.info['数据类型'] = type(data).__name__
self.info['数据规模'] = self._count_items(data)
self.info['数据结构'] = self._get_structure_summary(data)
# 可视化预览
preview = json.dumps(data, indent=2, ensure_ascii=False)[:1000]
self.info['内容预览'] = preview
except Exception as e:
logger.error(f"JSON处理失败: {e}")
self.info['JSON信息'] = f'读取失败: {e}'
return self.info
def _count_items(self, data):
"""递归计算数据项数量"""
if isinstance(data, list):
return len(data)
elif isinstance(data, dict):
return len(data)
return 1
def _get_structure_summary(self, data):
"""获取JSON结构摘要"""
if isinstance(data, dict):
keys = list(data.keys())[:10]
structure = f"键值: {keys}"
if len(data) > 10:
structure += f", 共{len(data)}个键"
return structure
elif isinstance(data, list):
structure = f"数组,共{len(data)}个元素"
if len(data) > 0:
structure += f",第一个元素类型: {type(data[0]).__name__}"
return structure
return f"简单类型: {type(data).__name__}"
def extract_all(self):
"""提取所有信息"""
self.extract_basic_info() # 基本信息对任何文件都适用
# 根据文件类型提取特定信息
ext = self.file_path.suffix.lower()
# 文本类文件
if ext in ['.txt', '.md', '.log', '.csv', '.html', '.xml', '.py', '.js', '.css']:
self.extract_text_info()
elif ext == '.pdf':
self.extract_pdf_info()
elif ext == '.docx':
self.extract_docx_info()
elif ext == '.xlsx':
self.extract_xlsx_info()
elif ext in ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp']:
self.extract_image_info()
elif ext == '.json':
self.extract_json_info()
else:
self.info['文件摘要'] = '不支持的特定内容提取'
return self.info
def extract_summary_from_file(file_path: str) -> Dict[str, Any]:
"""从单个文件提取摘要"""
extractor = FileInfoExtractor(file_path)
return extractor.extract_all()
def batch_extract(directory: str, output_format: str = 'json',
output_file: str = None, recursive: bool = False):
"""
批量提取文件摘要
Args:
directory: 要扫描的目录
output_format: 输出格式 (json/csv/excel)
output_file: 输出文件名
recursive: 是否递归处理子目录
"""
# 获取所有文件
base_path = Path(directory)
if recursive:
files = list(base_path.rglob('*'))
else:
files = list(base_path.iterdir())
# 过滤掉目录
files = [f for f in files if f.is_file()]
logger.info(f"找到 {len(files)} 个文件")
results = []
for idx, file_path in enumerate(files, 1):
try:
logger.info(f"[{idx}/{len(files)}] 正在处理: {file_path.name}")
file_info = extract_summary_from_file(file_path)
results.append(file_info)
except Exception as e:
logger.error(f"处理失败 {file_path}: {e}")
results.append({
'文件名': file_path.name,
'文件路径': str(file_path),
'错误信息': str(e)
})
# 输出结果
if output_file:
output_path = Path(output_file)
else:
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
output_path = Path(directory) / f'文件摘要_{timestamp}.{output_format}'
try:
if output_format == 'json':
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(results, f, ensure_ascii=False, indent=2)
elif output_format == 'csv':
# 获取所有可能的键
all_keys = set()
for result in results:
all_keys.update(result.keys())
with open(output_path, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=sorted(all_keys))
writer.writeheader()
writer.writerows(results)
elif output_format == 'excel':
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = '文件摘要'
# 创建表头
all_keys = sorted(set().union(*[r.keys() for r in results]))
ws.append(all_keys)
# 写入数据
for row in results:
ws.append([str(row.get(key, '')) for key in all_keys])
# 美化
from openpyxl.styles import Font, Alignment
header_font = Font(bold=True)
for cell in ws[1]:
cell.font = header_font
cell.alignment = Alignment(horizontal='center')
# 自动调整列宽
for column in ws.columns:
max_length = 0
column_letter = column[0].column_letter
for cell in column:
if cell.value:
max_length = max(max_length, len(str(cell.value)))
adjusted_width = min(max_length + 2, 50)
ws.column_dimensions[column_letter].width = adjusted_width
wb.save(output_path)
logger.info(f"摘要已保存到: {output_path}")
return results
except Exception as e:
logger.error(f"保存结果失败: {e}")
return results
def main():
"""主函数"""
parser = argparse.ArgumentParser(
description='批量提取文件摘要信息',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
# 提取当前目录所有文件
python file_extractor.py
# 提取指定目录
python file_extractor.py -d /path/to/directory
# 递归提取子目录
python file_extractor.py -d /path/to/directory -r
# 输出为Excel格式
python file_extractor.py -d /path/to/directory -f excel
# 指定输出文件
python file_extractor.py -d /path/to/directory -o 我的摘要.json
"""
)
parser.add_argument('-d', '--directory',
default='.',
help='要扫描的目录 (默认: 当前目录)')
parser.add_argument('-f', '--format',
choices=['json', 'csv', 'excel'],
default='json',
help='输出格式 (默认: json)')
parser.add_argument('-o', '--output',
help='输出文件路径 (可选)')
parser.add_argument('-r', '--recursive',
action='store_true',
help='递归处理子目录')
args = parser.parse_args()
# 验证目录存在
if not os.path.exists(args.directory):
logger.error(f"目录不存在: {args.directory}")
return
# 执行批量提取
batch_extract(
directory=args.directory,
output_format=args.format,
output_file=args.output,
recursive=args.recursive
)
if __name__ == "__main__":
main()
使用说明
安装依赖
pip install PyPDF2 python-docx openpyxl pillow
基本用法
# 提取当前目录所有文件 python file_extractor.py # 提取指定目录 python file_extractor.py -d /path/to/your/directory # 递归提取子目录 python file_extractor.py -d /path/to/directory -r # 输出为Excel格式 python file_extractor.py -d /path/to/directory -f excel # 指定输出文件名 python file_extractor.py -d /path/to/directory -o 我的摘要.json
功能特点
- 支持格式:PDF、Word、Excel、图片、文本、JSON等多种格式
- 基本信息:文件名、大小、时间、MD5哈希等提取**:根据文件类型提取特定信息
- 多种输出:JSON、CSV、Excel格式
- 递归扫描:可处理子目录
- 日志记录:详细的操作日志
输出示例
输出的JSON文件结构类似于:
[
{
"文件名": "报告.pdf",
"文件路径": "/path/to/报告.pdf",
"文件大小": "245.67 KB",
"创建时间": "2024-01-15 10:30:00",
"文件类型": ".pdf",
"页数": 5,
"PDF标题": "季度报告",
"PDF作者": "张三"
},
...
]
这个脚本可以很好地满足批量提取文件摘要的需求,您可以根据实际需要调整提取的字段和格式。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播