如何在Synapse中用Python读取ADLS Gen2的PDF/PPTX等多格式文件?
在Azure Synapse Notebook中读取ADLS Gen2非文本格式文件的解决方案
问题原因
你用到的python-pptx、pypdf、python-docx、extract_msg等第三方库,都是基于本地文件系统API设计的,不支持直接识别abfs/abfss协议路径。而Synapse中Spark能读取CSV/Excel等文件,是因为Spark封装了云存储协议适配,但这些第三方库没有做适配;挂载存储也只是Spark层面的映射,本地Python进程无法直接访问,所以会报FileNotFoundError。
解决方案
核心思路:先将ADLS Gen2中的文件下载到Synapse Notebook的本地临时存储(如/tmp目录),再用第三方库解析本地临时文件。以下提供两种实现方式:
方式1:用Spark读取二进制文件到本地
无需额外安装存储SDK,利用Spark自带的binaryFile格式读取文件内容,再写入本地临时路径:
# 1. 读取ADLS中的二进制文件 df = spark.read.format("binaryFile").load("abfss://file_system_name@account_name.dfs.core.windows.net/your_file_path") # 2. 提取文件内容和文件名 file_content = df.select("content").first()[0] file_name = df.select("path").first()[0].split("/")[-1] local_temp_path = f"/tmp/{file_name}" # 3. 写入本地临时文件 with open(local_temp_path, "wb") as f: f.write(file_content)
方式2:用Azure Storage SDK下载文件到本地
适合需要更灵活控制文件操作的场景,需先安装依赖库:
!pip install azure-storage-file-datalake
然后执行下载逻辑:
from azure.storage.filedatalake import DataLakeFileClient import os # 配置ADLS连接信息 account_name = "your_account_name" file_system_name = "your_file_system" file_path = "your_file_path" sas_token = "your_sas_token" # 或使用服务主体认证 # 初始化文件客户端并下载到本地 file_client = DataLakeFileClient( account_url=f"https://{account_name}.dfs.core.windows.net", file_system_name=file_system_name, file_path=file_path, credential=sas_token ) local_temp_path = f"/tmp/{os.path.basename(file_path)}" with open(local_temp_path, "wb") as local_file: download_stream = file_client.download_file() local_file.write(download_stream.readall())
各类型文件解析示例
下载完成后,即可用你熟悉的代码解析本地临时文件:
PDF文件
from pypdf import PdfReader reader = PdfReader(local_temp_path) # 提取每页文本 for page in reader.pages: print(page.extract_text())
PPTX文件
from pptx import Presentation prs = Presentation(local_temp_path) # 提取每页文本内容 for slide in prs.slides: for shape in slide.shapes: if hasattr(shape, "text"): print(shape.text)
DOCX文件
import docx doc = docx.Document(local_temp_path) # 提取段落文本 for para in doc.paragraphs: print(para.text)
EML文件
import email with open(local_temp_path, 'rb') as eml_file: msg = email.message_from_file(eml_file) # 提取邮件核心信息 print("主题:", msg["Subject"]) print("发件人:", msg["From"]) print("正文:", msg.get_payload())
MSG文件
import extract_msg msg = extract_msg.Message(local_temp_path) # 提取邮件核心信息 print("主题:", msg.subject) print("发件人:", msg.sender) print("正文:", msg.body)
清理临时文件(可选)
解析完成后,可删除本地临时文件释放空间:
import os os.remove(local_temp_path)
内容的提问来源于stack exchange,提问作者EB613
相关产品推荐
相关产品推荐

