使用PyPDF2提取PDF文本时数字显示异常的技术咨询
问题原因分析
这种情况我之前处理过,核心问题出在PDF文件的字符编码或字体渲染逻辑上:
- 小数点后的带删除线的
0̸0̸,大概率是标准数字0(U+0030)叠加了Unicode组合删除线字符(U+0338),PyPDF2提取时会把这两个组合字符一起抓出来,所以显示成带删除线的样子。 - 复制到表单变成
534,OOO.00,说明PDF里逗号后的三个“0”根本不是标准数字0,而是大写字母O(U+004F)——有些PDF生成工具(尤其是老旧的或非专业的)会用字体让O看起来和0一模一样,提取或复制时就会露馅。
解决方案
咱们分三步来搞定:
1. 先搞清楚异常字符的真实编码
先写一段小代码,打印提取文本中每个字符的Unicode编码,确认到底是哪种异常:
extracted_text = "你提取到的那个文本内容" for char in extracted_text: print(f"'{char}' 的Unicode编码: U+{ord(char):04X}")
比如:
- 如果看到
U+004F,那就是大写字母O; - 如果看到
U+0338,那就是组合删除线字符; - 标准数字0的编码是
U+0030。
2. 针对性清理异常字符
根据上面的排查结果,用代码替换成标准数字:
情况1:处理带删除线的0
用unicodedata模块过滤掉组合标记类字符(删除线属于这类):
import unicodedata def clean_strikethrough_chars(text): # 过滤掉所有Unicode标记类(非间距)字符 return ''.join(c for c in text if unicodedata.category(c) != 'Mn') cleaned_text = clean_strikethrough_chars(extracted_text)
情况2:把字母O替换成0
直接做字符串替换,或者用正则覆盖全角/半角的O:
import re def replace_o_with_zero(text): # 匹配半角O、半角o、全角O、全角o,替换成0 return re.sub(r'[Oo0O]', '0', text) cleaned_text = replace_o_with_zero(extracted_text)
情况3:组合处理
把两种情况结合起来:
import unicodedata import re def clean_numeric_text(text): # 先过滤删除线 text = ''.join(c for c in text if unicodedata.category(c) != 'Mn') # 再替换O为0 text = re.sub(r'[Oo0O]', '0', text) return text cleaned_text = clean_numeric_text(extracted_text)
3. 换用更精准的PDF提取库
如果PyPDF2的字符解析还是有问题,可以试试pdfplumber——它对PDF的字体结构和字符映射解析更细致,能减少这类异常:
import pdfplumber with pdfplumber.open("你的PDF文件路径.pdf") as pdf: # 提取第一页的文本,你可以循环处理所有页 page = pdf.pages[0] text = page.extract_text() # 再用上面的清理函数处理 cleaned_text = clean_numeric_text(text)
内容的提问来源于stack exchange,提问作者user9371615
相关产品推荐
相关产品推荐

