#!/usr/bin/env python3 """ 调试和测试脚本 用于诊断 EPUB 解析问题 """ import sys from pathlib import Path # 添加 src 目录到路径 sys.path.insert(0, str(Path(__file__).parent / "src")) from src.epub_parser import EPUBParser from src.text_processor import TextProcessor from src.utils import load_config from rich.console import Console from rich.table import Table from rich.panel import Panel from bs4 import BeautifulSoup import ebooklib def debug_epub_structure(epub_path: str): """调试 EPUB 结构""" console = Console() try: # 加载配置 config = load_config('config/config.json') # 初始化解析器 parser = EPUBParser(epub_path) text_processor = TextProcessor(config) console.print(f"[bold blue]调试 EPUB 文件: {epub_path}[/bold blue]\n") # 显示基本信息 book_info = parser.get_book_info() info_table = Table(title="书籍信息") info_table.add_column("属性", style="cyan") info_table.add_column("值", style="white") for key, value in book_info.items(): info_table.add_row(key, str(value)) console.print(info_table) # 显示目录结构 console.print("\n[bold green]目录结构分析:[/bold green]") toc_table = Table(title="目录结构") toc_table.add_column("类型", style="cyan") toc_table.add_column("标题", style="white") toc_table.add_column("状态", style="green") # 检查各种内容类型 content_types = ['preface', 'introduction', 'prologue', 'abstract', 'epilogue', 'acknowledgments'] for content_type in content_types: item = parser.toc_structure.get(content_type) if item: toc_table.add_row(content_type, item['title'], "✓ 找到") else: toc_table.add_row(content_type, "-", "✗ 未找到") # 章节信息 chapters = parser.toc_structure['chapters'] toc_table.add_row("chapters", f"{len(chapters)} 个章节", "✓ 找到" if chapters else "✗ 未找到") console.print(toc_table) # 显示章节列表 if chapters: console.print("\n[bold yellow]章节列表:[/bold yellow]") chapter_table = Table() chapter_table.add_column("序号", style="cyan") chapter_table.add_column("标题", style="white") chapter_table.add_column("内容长度", style="green") for i, chapter in enumerate(chapters[:10], 1): # 只显示前10个 content = parser._extract_item_content(chapter) content_length = len(content) if content else 0 chapter_table.add_row(str(i), chapter['title'], f"{content_length:,} 字符") if len(chapters) > 10: chapter_table.add_row("...", f"还有 {len(chapters) - 10} 个章节", "...") console.print(chapter_table) # 测试段落提取 console.print("\n[bold magenta]段落提取测试:[/bold magenta]") # 选择第一个有内容的项目进行测试 test_content = None test_title = "" # 优先测试序言类内容 for content_type in ['prologue', 'preface', 'introduction', 'abstract']: item = parser.toc_structure.get(content_type) if item: test_content = parser._extract_item_content(item) test_title = f"{content_type}: {item['title']}" break # 如果没有序言,测试第一个章节 if not test_content and chapters: test_content = parser._extract_item_content(chapters[0]) test_title = f"章节: {chapters[0]['title']}" if test_content: paragraphs = text_processor.extract_paragraphs(test_content) console.print(f"测试内容: {test_title}") console.print(f"原始内容长度: {len(test_content):,} 字符") console.print(f"提取段落数: {len(paragraphs)}") if paragraphs: # 显示前几个段落 para_table = Table(title="段落示例") para_table.add_column("序号", style="cyan") para_table.add_column("类型", style="yellow") para_table.add_column("内容预览", style="white") para_table.add_column("长度", style="green") for i, para in enumerate(paragraphs[:5], 1): preview = para['text'][:100] + "..." if len(para['text']) > 100 else para['text'] para_table.add_row( str(i), para.get('type', 'unknown'), preview, str(len(para['text'])) ) console.print(para_table) # 测试翻译块创建 chunks = text_processor.create_chunks(paragraphs, 3) console.print(f"\n[cyan]翻译块信息:[/cyan] 创建了 {len(chunks)} 个翻译块") if chunks: chunk_table = Table(title="翻译块示例") chunk_table.add_column("块号", style="cyan") chunk_table.add_column("段落数", style="yellow") chunk_table.add_column("总字符数", style="green") for i, chunk in enumerate(chunks[:3], 1): # 显示前3个块 total_chars = sum(len(p['text']) for p in chunk) chunk_table.add_row(str(i), str(len(chunk)), f"{total_chars:,}") console.print(chunk_table) else: console.print("[red]未能提取到段落![/red]") # 显示原始内容的一部分用于调试 soup = BeautifulSoup(test_content, 'html.parser') text_content = soup.get_text()[:500] console.print(Panel( text_content, title="原始文本内容(前500字符)", border_style="red" )) else: console.print("[red]未找到可测试的内容![/red]") # 显示所有 HTML 文件 console.print("\n[bold cyan]所有 HTML 文件:[/bold cyan]") try: html_items = list(parser.book.get_items_of_type(ebooklib.ITEM_DOCUMENT)) file_table = Table() file_table.add_column("文件名", style="cyan") file_table.add_column("大小", style="green") file_table.add_column("内容预览", style="white") for item in html_items[:10]: # 只显示前10个 try: content = item.get_content().decode('utf-8', errors='ignore') soup = BeautifulSoup(content, 'html.parser') text_preview = soup.get_text()[:100].replace('\n', ' ') file_table.add_row( item.get_name(), f"{len(content):,} 字符", text_preview + "..." if len(text_preview) == 100 else text_preview ) except Exception as e: file_table.add_row(item.get_name(), "错误", f"读取失败: {e}") if len(html_items) > 10: file_table.add_row("...", f"还有 {len(html_items) - 10} 个文件", "...") console.print(file_table) except Exception as e: console.print(f"[yellow]无法列出 HTML 文件: {e}[/yellow]") # 总结 console.print(f"\n[bold green]✓ 调试完成[/bold green]") console.print(f"[green]结论: EPUB 文件结构正常,可以进行翻译[/green]") except Exception as e: console.print(f"[red]调试失败: {e}[/red]") import traceback console.print(traceback.format_exc()) if __name__ == "__main__": if len(sys.argv) != 2: print("使用方法: python debug.py ") sys.exit(1) epub_file = sys.argv[1] debug_epub_structure(epub_file)