{"record":{"id":"f568ba26763375c3","repo":"binary-husky/gpt_academic","slug":"pdf-fp","errorCode":null,"errorMessage":"抱歉, 我们暂时无法解析此PDF文档: {fp}。","messagePattern":"抱歉, 我们暂时无法解析此PDF文档: (.+?)。","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"crazy_functions/crazy_utils.py","lineNumber":444,"sourceCode":"            meta_txt.extend([\" \".join([\"\".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(\n                '- ', '') for t in text_areas['blocks'] if 'lines' in t])\n            meta_font.extend([np.mean([np.mean([wtf['size'] for wtf in l['spans']])\n                             for l in t['lines']]) for t in text_areas['blocks'] if 'lines' in t])\n            if index == 0:\n                page_one_meta = [\" \".join([\"\".join([wtf['text'] for wtf in l['spans']]) for l in t['lines']]).replace(\n                    '- ', '') for t in text_areas['blocks'] if 'lines' in t]\n\n        ############################## <第 2 步，获取正文主字体> ##################################\n        try:\n            fsize_statistics = {}\n            for span in meta_span:\n                if span[1] not in fsize_statistics: fsize_statistics[span[1]] = 0\n                fsize_statistics[span[1]] += span[2]\n            main_fsize = max(fsize_statistics, key=fsize_statistics.get)\n            if REMOVE_FOOT_NOTE:\n                give_up_fize_threshold = main_fsize * REMOVE_FOOT_FFSIZE_PERCENT\n        except:\n            raise RuntimeError(f'抱歉, 我们暂时无法解析此PDF文档: {fp}。')\n        ############################## <第 3 步，切分和重新整合> ##################################\n        mega_sec = []\n        sec = []\n        for index, line in enumerate(meta_line):\n            if index == 0:\n                sec.append(line[fc])\n                continue\n            if REMOVE_FOOT_NOTE:\n                if meta_line[index][fs] <= give_up_fize_threshold:\n                    continue\n            if ffsize_same(meta_line[index][fs], meta_line[index-1][fs]):\n                # 尝试识别段落\n                if meta_line[index][fc].endswith('.') and\\\n                    (meta_line[index-1][fc] != 'NEW_BLOCK') and \\\n                    (meta_line[index][fb][2] - meta_line[index][fb][0]) < (meta_line[index-1][fb][2] - meta_line[index-1][fb][0]) * 0.7:\n                    sec[-1] += line[fc]\n                    sec[-1] += \"\\n\\n\"\n                else:","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/crazy_utils.py#L426-L462","documentation":"read_and_clean_pdf_text's second stage builds a font-size histogram from PyMuPDF spans and calls max() on it. If the PDF yields no text spans, max() raises ValueError and the bare except converts it to this generic RuntimeError. The most common cause is an image-only/scanned PDF, but any exception while computing the main font is hidden.","triggerScenarios":"fitz.open() succeeds but page.get_text('dict') produces no lines/spans, so meta_span is empty; or span data is malformed. Scanned pages, image-only exports, some encrypted PDFs, and unusual PDF generators trigger it.","commonSituations":"Scanned papers loaded into PDF summarization/translation; a PDF containing only images; a password-protected or damaged PDF; a version-specific PyMuPDF extraction issue.","solutions":["Confirm the PDF contains selectable text rather than page images.","OCR the PDF first, for example with OCRmyPDF or Tesseract, and retry.","Use an alternative parser such as Grobid or doc2x if available in this project.","Remove password protection/repair the PDF before uploading.","Replace the bare except with a specific check for empty meta_span and include the original exception."],"exampleFix":"# before\ntry:\n    fsize_statistics = {}\n    ...\n    main_fsize = max(fsize_statistics, key=fsize_statistics.get)\nexcept:\n    raise RuntimeError(f'抱歉, 我们暂时无法解析此PDF文档: {fp}。')\n\n# after\nif not meta_span:\n    raise RuntimeError(f'PDF has no extractable text; run OCR first: {fp}')\ntry:\n    ...\n    main_fsize = max(fsize_statistics, key=fsize_statistics.get)\nexcept Exception as e:\n    raise RuntimeError(f'抱歉, 我们暂时无法解析此PDF文档: {fp}: {e}') from e\n","handlingStrategy":"validation","validationCode":"import fitz\n\ndef pdf_has_extractable_text(fp, sample_pages=3) -> bool:\n    with fitz.open(fp) as doc:\n        pages = doc[:sample_pages] if len(doc) >= sample_pages else doc\n        return any(page.get_text().strip() for page in pages)\n","typeGuard":"def is_text_pdf(fp: str) -> bool:\n    try:\n        with fitz.open(fp) as doc:\n            return any(page.get_text().strip() for page in doc)\n    except Exception:\n        return False\n","tryCatchPattern":"try:\n    file_content, page_one = read_and_clean_pdf_text(fp)\nexcept RuntimeError as e:\n    if \"无法解析此PDF\" in str(e):\n        route_pdf_to_ocr_or_alternate_parser(fp)\n    else:\n        raise\n","preventionTips":["Check for extractable text before using the layout/font parser.","OCR scanned PDFs before summarization or translation.","Reject encrypted PDFs with a clear message.","Never use a bare except around font analysis; preserve the cause."],"tags":["pdf","pymupdf","ocr","parsing"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}