GoogleDriveの指定フォルダからファイルを取得し処理

GoogleDriveの指定フォルダからファイルを取得し処理

Google Drive API でフォルダのIDを取得できたので
次にここにpdfファイルを配置して
これを取得しテキストを抽出する

PyPDF2 と pdfminer.six はどちらも PDF ファイルを操作するための Python ライブラリ

PyPDF2 には PDF ファイルの結合、分割、ページの回転、ページの追加・削除など、PDF のページ操作機能が充実

pdfminer.six は PDF を読み取ってテキストデータを抽出することが主目的のため、ページ操作や編集の機能はない

PyPDF2 は比較的軽量で、簡単なテキスト抽出やページ操作には高速に動作しますが、PDFの内容解析が簡易的

pdfminer.six はテキスト抽出においては非常に詳細な処理を行うため、
特に長い PDF や複雑なレイアウトのファイルでは処理時間が長くなる

ということでpdfminer.sixを使いテキストを取り出す

そしてその処理結果を渡すというモジュールを作成する

Google Drive の
School フォルダの ID: ここからpdfファイルを取得し
pdfminer.sixを使ってPDFからテキストを抽出したい

Google Drive の School フォルダの ID:
ここからpdfファイルを取得し pdfminer.sixを使ってPDFからテキストを抽出したい
個人で使うので token.jsonを使ったコードにする
抽出したテキストを処理する関数に渡すようにするため 抽出したテキストをOllamaに送信は不要。

import os
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from googleapiclient.http import MediaIoBaseDownload
from pdfminer.high_level import extract_text
from io import BytesIO

# Google Drive APIの認証
def authenticate_drive():
    SCOPES = ['https://www.googleapis.com/auth/drive']
    creds = None
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    else:
        print("認証トークンが見つかりません。認証を実行してください。")
        return None
    return build('drive', 'v3', credentials=creds)

# フォルダ内のPDFファイルリストを取得
def list_pdf_files_in_folder(service, folder_id):
    """Google Driveフォルダ内のPDFファイルのリストを取得します"""
    query = f"'{folder_id}' in parents and mimeType='application/pdf'"
    results = service.files().list(q=query, fields="files(id, name)").execute()
    files = results.get('files', [])
    return files

# Google DriveからPDFファイルをダウンロード
def download_pdf_from_drive(service, file_id):
    """Google DriveからPDFファイルをダウンロードし、バイナリデータを返します"""
    request = service.files().get_media(fileId=file_id)
    file_data = BytesIO()
    downloader = MediaIoBaseDownload(file_data, request)
    done = False
    while not done:
        status, done = downloader.next_chunk()
        print(f"Download Progress: {int(status.progress() * 100)}%")
    file_data.seek(0)
    return file_data

# PDFからテキストを抽出
def extract_text_from_pdf(pdf_data):
    """PDFファイルデータからテキストを抽出します"""
    text = extract_text(pdf_data)
    return text

# テキストを処理する関数
def process_text(text):
    """抽出したテキストを処理します"""
    print("Extracted Text:\n", text)
    # テキストの処理ロジックをここに追加します

# フォルダ内のPDFを処理
def process_pdfs_in_folder(folder_id):
    service = authenticate_drive()
    if not service:
        return

    pdf_files = list_pdf_files_in_folder(service, folder_id)
    if not pdf_files:
        print("指定されたフォルダにPDFファイルが見つかりません。")
        return

    for pdf_file in pdf_files:
        print(f"Processing file: {pdf_file['name']}")
        pdf_data = download_pdf_from_drive(service, pdf_file['id'])
        pdf_text = extract_text_from_pdf(pdf_data)
        if pdf_text:
            process_text(pdf_text)
        else:
            print(f"{pdf_file['name']} からテキストを抽出できませんでした。")

# フォルダIDを指定して処理を開始
folder_id = ""  # SchoolフォルダのID
process_pdfs_in_folder(folder_id)

これを

python get_pdf_read.py

で実行するとかなりの精度で取り出すことができた

次はこれをモジュールにしてollamaに処理結果を渡せるようにする

なおコード解説は
コードの説明
1. authenticate_drive関数: token.jsonを使用してGoogle Drive APIに認証し、Driveサービスを取得
2. list_pdf_files_in_folder関数: 指定したフォルダID内のPDFファイルをリスト化
3. download_pdf_from_drive関数: 各PDFファイルをダウンロードし、バイナリデータを返す
4. extract_text_from_pdf関数: pdfminer.sixを使ってPDFデータからテキストを抽出
5. process_text関数: 抽出したテキストを処理します。ここに任意の処理ロジックを追加
6. process_pdfs_in_folder関数: フォルダ内の全PDFファイルを処理し、各PDFのテキストを抽出後にprocess_text関数に渡す
これで、抽出されたテキストを直接処理する

なおGPTで生成したコードでは

SCOPES = ['https://www.googleapis.com/auth/drive.readonly']

というスコープだが
これだと認証エラーになる

    SCOPES = ['https://www.googleapis.com/auth/drive']

で回避可能

これは google カレンダーの時も同様で

SCOPES = ['https://www.googleapis.com/auth/calendar']

なら認証エラーにならない

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です