pathlib / os / pandas 与第三方提取库

面向 PDF & Markdown 提取场景


一、pathlib—— 面向对象的路径操作(现代首选)

pathlib把路径当成对象而不是字符串,链式调用更直观。Path是 Python 3.4+ 开始官方推荐的文件路径处理方式,比传统的os.path更直观、更优雅。对"提取 PDF / Markdown"这种场景,它负责定位和读取文件

1. 创建路径对象(支持/拼接,超级方便)

frompathlibimportPath# / 运算符直接拼接,不用再写 os.path.joinp=Path("D:/test")/"dm_projects"/"data.csv"print(f"路径:{p}")

2. 提取文件名、后缀、纯文件名(提取场景高频用到)

print(f"完整文件名:{p.name}")# data.csvprint(f"后缀:{p.suffix}")# .csvprint(f"纯文件名(无后缀):{p.stem}")# data <--- 过滤/重命名时核心print(f"父目录:{p.parent}")# D:/test/dm_projects

3. 判断存在性与类型

print(f"存在吗?{p.exists()}")print(f"是文件吗?{p.is_file()}")# Trueprint(f"是目录吗?{p.is_dir()}")# False

4. 创建目录(自动创建父级,不怕报错)

out=Path("D:/test/dm_projects/output")out.mkdir(parents=True,exist_ok=True)# 父目录不存在也会一并创建,已存在也不报错

5. 递归找出 PDF / MD 并读取

root=Path('D:/project/docs')files=list(root.rglob('*'))pdfs=[pforpinfilesifp.suffix.lower()=='.pdf']mds=[pforpinfilesifp.suffix.lower()=='.md']formdinmds:text=md.read_text(encoding='utf-8')# Markdown = 纯文本,读完即用forpdfinpdfs:raw=pdf.read_bytes()# PDF 是二进制,还看不懂

常用成员:rglob()(递归通配)、read_text()read_bytes()exists()is_file()stat().st_size(拿文件大小)、mkdir()


二、os—— 经典过程式文件操作(底层可控)

os更"命令式",适合写脚本时做精细控制。和pathlib干的活一样,只是写法更啰嗦:

importos root='D:/project/docs'fordirpath,_,filenamesinos.walk(root):forfninfilenames:iffn.lower().endswith(('.pdf','.md')):full=os.path.join(dirpath,fn)iffn.lower().endswith('.md'):text=open(full,encoding='utf-8').read()

os.walk()在需要边走边过滤时很顺手;os.path系列(join/exists/splitext)做字符串拼路径也行。


三、pathlibos.path对照表(核心区别)

两者功能等价,只是 API 风格不同。能对照着记就最清楚:

需求pathlib(对象式)os.path(函数式)
拼接路径Path(a) / b / cos.path.join(a, b, c)
完整文件名p.nameos.path.basename(p)
后缀p.suffixos.path.splitext(p)[1]
纯文件名(无后缀)p.stemos.path.splitext(p)[0]
父目录p.parentos.path.dirname(p)
是否存在p.exists()os.path.exists(p)
是否文件p.is_file()os.path.isfile(p)
是否目录p.is_dir()os.path.isdir(p)
创建多级目录p.mkdir(parents=True, exist_ok=True)os.makedirs(p, exist_ok=True)
绝对路径p.resolve()/p.absolute()os.path.abspath(p)
遍历目录p.iterdir()/p.rglob('*')os.listdir()/os.walk()

风格差异小结

  • pathlib:路径即对象,方法链式调用,跨平台(\/自动处理),可读性高 → 新项目首选。
  • os.path:路径即字符串,函数式调用,老代码/需要精细系统交互时常见 → 维护老脚本不必强行改。
  • 本质:pathlib在底层也是对字符串做同样的处理,只是把操作封装成了对象方法。

四、pandas—— 表格数据提取(不是 PDF/MD,但是"内容进 DataFrame"的桥)

pandas本身不解析PDF/MD,但一旦你把内容抽出来变成结构化数据,它是最快的清洗/分析工具:

importpandasaspd df=pd.read_csv('extracted.csv')print(df.shape,df.columns)subset=df[df['type'].isin(['pdf','md'])]

常见读取器:read_csv/read_excel/read_json/read_parquet当你要"对提取结果做统计"时上 pandas,而不是用它去读原始 PDF。


五、专门做"内容提取"的第三方库(按格式分)

os/pathlib只拿到文件,要"读懂里面写了什么"得靠这些:

PDF 提取

特点
pdfplumber最易上手,extract_text()/ 按页 / 抽表格
PyPDF2轻量,基础文本和合并拆分
fitz(PyMuPDF)速度最快,还能转图、抽版式
importpdfplumberwithpdfplumber.open('report.pdf')aspdf:page1=pdf.pages[0].extract_text()# 这才是"读懂了 PDF"

Markdown

Markdown本身就是纯文本,pathlib读完就能用。只有你想识别标题/链接结构时才需解析库(如markdown转 HTML)。多数情况不需要。

Office / 其他

用途
python-docx抽 Word 文字/表格
openpyxl读 Excel 单元格
python-pptx抽 PPT 文本
tabula-pyPDF 里的表格 → DataFrame

六、组合实战(典型提取流程)

frompathlibimportPathimportpdfplumber,pandasaspd root=Path('D:/docs')records=[]forpinroot.rglob('*'):ifp.suffix.lower()=='.pdf':withpdfplumber.open(p)aspdf:text=pdf.pages[0].extract_text()records.append({'file':str(p),'type':'pdf','text':text})elifp.suffix.lower()=='.md':records.append({'file':str(p),'type':'md','text':p.read_text(encoding='utf-8')})df=pd.DataFrame(records)df.to_csv('extracted.csv',index=False)

总结分层:pathlib/os负责"找到并读出文件" →pdfplumber/fitz负责"从 PDF 二进制里抽出文字" →pandas负责"对抽出的内容做统计"。Markdown 因为本就是文本,第二层可以省掉。