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_projects3. 判断存在性与类型
print(f"存在吗?{p.exists()}")print(f"是文件吗?{p.is_file()}")# Trueprint(f"是目录吗?{p.is_dir()}")# False4. 创建目录(自动创建父级,不怕报错)
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)做字符串拼路径也行。
三、pathlib与os.path对照表(核心区别)
两者功能等价,只是 API 风格不同。能对照着记就最清楚:
| 需求 | pathlib(对象式) | os.path(函数式) |
|---|---|---|
| 拼接路径 | Path(a) / b / c | os.path.join(a, b, c) |
| 完整文件名 | p.name | os.path.basename(p) |
| 后缀 | p.suffix | os.path.splitext(p)[1] |
| 纯文件名(无后缀) | p.stem | os.path.splitext(p)[0] |
| 父目录 | p.parent | os.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-py | PDF 里的表格 → 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 因为本就是文本,第二层可以省掉。