我正在尝试创建一个 lambda 函数,该函数将访问上传到 s3 的 pdf 表单,并删除输入到表单中的数据并将其发送到其他地方。
当我可以在本地下载文件时,我就可以执行此操作。所以下面的脚本可以工作并允许我将 pdf 中的数据读取到我的 pandas 数据框中。:
import PyPDF2 as pypdf
import pandas as pd
s3 = boto3.resource('s3')
s3.meta.client.download_file(bucket_name, asset_key, './target.pdf')
pdfobject = open("./target.pdf", 'rb')
pdf = pypdf.PdfFileReader(pdfobject)
data = pdf.getFormTextFields()
pdf_df = pd.DataFrame(data, columns=get_cols(data), index=[0])
但是使用 lambda 我无法在本地保存文件,因为我收到“只读文件系统”错误。
我尝试使用 s3.get_object() 方法,如下所示:
s3_response_object= s3.get_object(
Bucket='pdf-forms-bucket',
Key='target.pdf',
)
pdf_bytes = s3_response_object['Body'].read()
但我不知道如何将生成的字节转换为可以用 PyDF2 解析的对象。我需要的输出以及 PyDF2 将产生的输出如下所示:
{'form1[0].#subform[0].nameandmail[0]': 'Burt Lancaster',
'form1[0].#subform[0].mailaddress[0]': '675 Creighton Ave, Washington DC',
'form1[0].#subform[0].Principal[0]': 'David St. Hubbins',
'Principal[1]': None,
'form1[0].#subform[0].Principal[2]': 'Bart Simpson',
'Principal[3]': None}
总而言之,我需要能够读取带有可填写表单的 pdf、将其读入内存并解析它,而无需下载文件,因为我的 lambda 函数环境不允许本地临时文件。
boto3
库似乎发生了变化,这是最新的解决方案
from io import BytesIO
import boto3
from PyPDF2 import PdfReader
s3 = boto3.client("s3")
pdf_file = s3.get_object(Bucket="***", Key="***")[
"Body"
].read()
reader = PdfReader(BytesIO(pdf_file))
for page in reader.pages:
print(f"Text: {page.extract_text()}")
解决了,这个就可以了:
import boto3
from PyPDF2 import PdfFileReader
from io import BytesIO
bucket_name ="pdf-forms-bucket"
item_name = "form.pdf"
s3 = boto3.resource('s3')
obj = s3.Object(bucket_name, item_name)
fs = obj.get()['Body'].read()
pdf = PdfFileReader(BytesIO(fs))
data = pdf.getFormTextFields()
感谢@Harrison 提供之前的解决方案,请在下面找到替代解决方案:
import boto3
from io import BytesIO
from PyPDF2 import PdfReader
s3 = boto3.resource(service_name = "s3",
region_name = "your_region_name",
aws_access_key_id = "your_key_id",
aws_secret_access_key = "your_key")
obj = s3.Bucket('your_bucket_name').Object('file_key').get()
reader = PdfReader(BytesIO(obj['Body'].read()))
for page in reader.pages:
print(f"Text: {page.extract_text()}")