Ver Fonte

feat: 检测MinerU识别异常(同字重复)时用Paddle doc_parser结果替换markdown再解析

Co-authored-by: Cursor <cursoragent@cursor.com>
何文松 há 2 semanas atrás
pai
commit
e69dff9ab7

+ 19 - 1
pdf_converter_v2/parser/json_converter.py

@@ -9,7 +9,7 @@ from copy import deepcopy
 from PIL import Image
 
 from ..utils.logging_config import get_logger
-from ..utils.paddleocr_fallback import fallback_parse_with_paddleocr, call_paddleocr
+from ..utils.paddleocr_fallback import fallback_parse_with_paddleocr, call_paddleocr, has_recognition_garbage
 from .document_type import detect_document_type
 from .noise_parser import parse_noise_detection_record
 from .electromagnetic_parser import parse_electromagnetic_detection_record
@@ -195,6 +195,24 @@ def parse_markdown_to_json(markdown_content: str, first_page_image: Optional[Ima
         input_file: 原始输入文件路径(PDF或图片),用于从PDF提取第一页
     """
     original_markdown = markdown_content
+
+    # 若检测到 MinerU 识别异常(如表格单元格内同一字符大量重复),用 Paddle doc_parser 结果替换后再解析
+    if enable_paddleocr_fallback and (output_dir or input_file) and has_recognition_garbage(markdown_content):
+        logger.warning("[JSON转换] 检测到MinerU识别异常(如重复字符),尝试使用Paddle doc_parser补充替换")
+        try:
+            fallback_markdown = fallback_parse_with_paddleocr(
+                json_data={"document_type": forced_document_type or "electromagneticTestRecord"},
+                markdown_content=markdown_content,
+                output_dir=output_dir,
+                document_type=forced_document_type,
+                input_file=input_file,
+            )
+            if fallback_markdown:
+                markdown_content = fallback_markdown
+                original_markdown = markdown_content
+                logger.info("[JSON转换] 已用Paddle doc_parser结果替换Markdown,继续解析")
+        except Exception as e:
+            logger.warning(f"[JSON转换] Paddle doc_parser补充替换失败,继续使用原Markdown: {e}")
     
     logger.info(f"[JSON转换] 开始解析,forced_document_type={forced_document_type}")
     

+ 16 - 0
pdf_converter_v2/utils/paddleocr_fallback.py

@@ -138,6 +138,22 @@ def _paddle_ocr_device_args() -> list:
     return ["--device", device]
 
 
+def has_recognition_garbage(text: str, min_repeat: int = 10) -> bool:
+    """检测文本中是否存在同一字符连续重复的识别异常(如 MinerU 误识别的 草草草...)。
+    用于在解析前判断是否应用 Paddle doc_parser 做补充替换。
+    
+    Args:
+        text: 待检测的 markdown/文本
+        min_repeat: 同一字符连续出现次数超过此值视为异常,默认 10
+        
+    Returns:
+        True 表示存在疑似识别异常
+    """
+    if not text or len(text) < min_repeat:
+        return False
+    return bool(re.search(rf"(.)\1{{{min_repeat},}}", text))
+
+
 def detect_file_type(file_path: str) -> Optional[str]:
     """通过文件内容(魔数)检测文件类型,不依赖扩展名