gemini で広告解析とレシピ提案と読み上げ

https://axross-recipe.com/recipes/1741
を参考いgemini で広告解析とレシピ提案と読み上げ

pip install streamlit google-generativeai pillow pyttsx3

で必要なライブラリインストール

import streamlit as st
import google.generativeai as genai
from io import BytesIO
from PIL import Image  
import io
import pyttsx3
import queue

# Gemini API設定
genai.configure(api_key="YOUR_API_KEY_HERE")

# TTSエンジンの初期化
engine = pyttsx3.init()
is_speaking = False  # 音声合成中かどうかを示すフラグ
tts_queue = queue.Queue()  # 音声合成リクエストのキュー

def extract_text_from_image(image):
    model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest")
    response = model.generate_content([
        image,
        {"text": "画像からテキストを抽出してください。"}
    ])
    return response.text if response else ""

def parse_product_data(text):
    lines = text.split("\n")
    ingredients = set()

    for line in lines:
        line = line.strip()
        ingredients.update(line.split())
    return list(ingredients)

def suggest_recipes(ingredients):
    model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest")
    prompt = f"以下の食材を使って作れる料理のレシピを提案してください: {', '.join(ingredients)}"
    response = model.generate_content(prompt)
    return response.text if response else ""

def read_aloud(text):
    tts_queue.put(text)  # リクエストをキューに追加
    process_queue()  # キューを処理

def process_queue():
    global is_speaking

    if not tts_queue.empty() and not is_speaking:
        text = tts_queue.get()  # キューからテキストを取得
        is_speaking = True  # 音声合成中フラグを立てる
        engine.say(text)  # 音声合成を実行
        engine.runAndWait()  # 音声合成が完了するまで待機
        is_speaking = False  # 音声合成が完了したらフラグをリセット
        process_queue()  # 次のリクエストを処理

def start_reading(text):
    read_aloud(text)

st.title("チラシ画像からレシピ提案")

uploaded_file = st.file_uploader("チラシ画像をアップロード", type=["jpg", "png", "jpeg"])
if uploaded_file:
    st.image(uploaded_file, caption="アップロードされた画像", use_column_width=True)
    image_bytes = uploaded_file.read()
    image = Image.open(BytesIO(image_bytes))

    # 一時的に画像ファイルとして保存する例(環境に合わせて変更すること)
    img_byte_arr = io.BytesIO()
    image.save(img_byte_arr, format='PNG')
    img_byte_arr = img_byte_arr.getvalue()

    with open("uploaded_tirashi_image.png", "wb") as f:
        f.write(img_byte_arr)
    input_file = genai.upload_file(path="uploaded_tirashi_image.png", display_name="image")
    
    with st.spinner("データを解析中..."):
        extracted_text = extract_text_from_image(input_file)
    
    st.subheader("抽出されたテキスト")
    st.text_area("テキスト", extracted_text, height=200)

    ingredients = parse_product_data(extracted_text)

    if ingredients:
        st.subheader("提案されたレシピ")
        recipes = suggest_recipes(ingredients)
        st.write(recipes)
        if st.button("提案されたレシピを読み上げる"):
            # レシピが長すぎる場合は最初の部分だけ読み上げるなどの調整も可能
            start_reading("提案されたレシピは次の通りです。 " + recipes)
    
    # 停止ボタンの実装
    if st.button("読み上げ停止"):
        engine.stop()
        engine.endLoop()
        st.info("読み上げを停止しました。")

が全体コード

このコードはダウンロードできる
あとチラシ画像もダウンロードしておく

これでやることは
アップロードされたチラシ画像をGemini APIに送信し、商品情報やキャンペーン内容などのテキストを抽出

抽出されたテキストから使用可能な食材を解析し、Gemini APIにより最適なレシピを生成

Pyttsx3ライブラリを用い、提案された情報やレシピを音声で読み上げます。
ユーザーは「停止」ボタンにより、いつでも読み上げを中断

この中で欲しい機能は
Gemini のチラシ解析
Python でgemini の結果の読み上げ

 touch voice_resipi.py

でファイルを作成

import streamlit as st
import google.generativeai as genai
from io import BytesIO
from PIL import Image  
import io
import pyttsx3
import queue

で必要なライブラリのインポート

* streamlit: Webアプリ開発を簡単に行えるライブラリ。
* google.generativeai (Gemini): 画像やテキストの解析・生成を行うGoogleの生成AI。
* BytesIO, PIL.Image, io: 画像データの取り扱いに使用。
* pyttsx3: テキストを音声に変換するためのTTSライブラリ。
* queue: 複数の処理を順次実行するための仕組みを提供。

次にGemini APIとTTSエンジンの初期設定

# Gemini APIの設定
genai.configure(api_key="YOUR_API_KEY_HERE")

# TTSエンジンの初期化
engine = pyttsx3.init()
is_speaking = False  # 音声合成中かどうかのフラグ
tts_queue = queue.Queue()  # 音声合成リクエストのキュー

* APIキーを設定し、Geminiサービスの利用を可能にします。
* pyttsx3を初期化して音声読み上げの準備を行い、フラグとキューで複数のリクエストを管理

やっぱり設定は gemini.configure で行っている
以前参考にしたサイトのコードは間違っていた

https://qiita.com/shisuto3141/items/2f9349e96703c189f572
のように

self.client = genai.Client(api_key=API_KEY)

は間違い

次に画像からテキストを抽出する関数

def extract_text_from_image(image):
    model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest")
    response = model.generate_content([
        image,
        {"text": "画像からテキストを抽出してください。"}
    ])
    return response.text if response else ""

* アップロードされた画像をGemini APIに送信し、画像内の文字情報を抽出します。
* エラーが発生した場合は、空文字を返す

もし動かないのならモデル名を変更する

次に
テキストから商品情報を解析する関数

def parse_product_data(text):
    lines = text.split("\n")
    ingredients = set()
    
    for line in lines:
        line = line.strip()
        ingredients.update(line.split())
    return list(ingredients)

* 各行の単語をセットに追加して重複を排除し、食材や商品名を抽出

次に
Gemini APIでレシピを提案する関数

def suggest_recipes(ingredients):
    model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest")
    prompt = f"以下の食材を使って作れる料理のレシピを提案してください: {', '.join(ingredients)}"
    response = model.generate_content(prompt)
    return response.text if response else ""

* 解析された食材情報を基に、Gemini APIにレシピ生成を依頼します。
* 提案されたレシピをテキスト形式で返す

なおingreduebtsはリストで

def parse_product_data(text):

の処理結果の食材のリストになる

これを使って処理して結果はtext に入る
つまりgeminiの処理結果、つまり提案されたレシピがテキスト情報として格納される

次に音声読み上げリクエストを管理する関数群

リクエスト追加用関数を作成しておく

def read_aloud(text):
    tts_queue.put(text)  # 読み上げリクエストをキューに追加
    process_queue()      # キューを処理

これで
ユーザーが「読み上げ」ボタンを押すと、対象のテキストがキューに追加され、順次処理

次にリクエスト処理用関数

def process_queue():
    global is_speaking

    if not tts_queue.empty() and not is_speaking:
        text = tts_queue.get()  # キューからテキストを取得
        is_speaking = True      # 読み上げ中のフラグを立てる
        engine.say(text)        # テキストを音声合成
        engine.runAndWait()     # 読み上げ完了まで待機
        is_speaking = False     # フラグをリセット
        process_queue()         # 次のリクエストを処理

キューに溜まったリクエストを1件ずつ順次処理し、同時に複数の読み上げが行われないよう制御

次に ラッパー関数

def start_reading(text):
    read_aloud(text)

これは
「read_aloud」を呼び出すラッパー関数で、コード全体の可読性を向上

次にStreamlitによるWeb画面の基本設定

st.title("チラシ画像からレシピ提案")

アプリのタイトルをWeb画面に表示し、ユーザーに内容を即座に伝える

次に画像アップロード機能の実装

uploaded_file = st.file_uploader("チラシ画像をアップロード", type=["jpg", "png", "jpeg"])
if uploaded_file:
    st.image(uploaded_file, caption="アップロードされた画像", use_column_width=True)

ユーザーがチラシ画像をアップロードできるようにし、選択した画像を画面に表示

次に画像の読み込みと変換

    image_bytes = uploaded_file.read()
    image = Image.open(BytesIO(image_bytes))

アップロードされた画像ファイルをバイナリデータとして読み込み、PILで画像オブジェクトに変換

次に画像を一時ファイルとして保存

    # 一時的に画像ファイルとして保存する例(環境に合わせて調整してください)
    img_byte_arr = io.BytesIO()
    image.save(img_byte_arr, format='PNG')
    img_byte_arr = img_byte_arr.getvalue()

画像データをPNG形式で一時ファイルに変換し、Gemini APIに渡す準備を行う

次に画像ファイルのアップロードとGemini API連携

    with open("uploaded_tirashi_image.png", "wb") as f:
        f.write(img_byte_arr)
    input_file = genai.upload_file(path="uploaded_tirashi_image.png", display_name="image")

一時ファイルとして保存した画像をGemini APIへアップロードし、テキスト抽出を実行可能にする

次にテキスト抽出と結果表示

    with st.spinner("データを解析中..."):
        extracted_text = extract_text_from_image(input_file)
    
    st.subheader("抽出されたテキスト")
    st.text_area("テキスト", extracted_text, height=200)

処理中はスピナーを表示し、抽出されたテキストをテキストエリアでユーザーに提示

次にレシピの生成

    ingredients = parse_product_data(extracted_text)

抽出テキストから食材情報を解析し、該当する場合は音声読み上げ機能でお知らせ

次にレシピ提案の表示と音声読み上げ

    if ingredients:
        st.subheader("提案されたレシピ")
        recipes = suggest_recipes(ingredients)
        st.write(recipes)
        if st.button("提案されたレシピを読み上げる"):
            start_reading("提案されたレシピは次の通りです。 " + recipes)

解析した食材情報を元に、Gemini APIで生成されたレシピを画面に表示し、音声でも確認

次に読み上げ停止機能の実装

    if st.button("読み上げ停止"):
        engine.stop()
        engine.endLoop()
        st.info("読み上げを停止しました。")

ユーザーが「読み上げ停止」ボタンを押すと、現在の音声再生を即座に中断し、停止完了のメッセージを表示

これらを保存し

streamlit run voice_resipi.py 

で起動
自動でブラウザが立ち上がるので
テスト画像をアップ
すると食材とレシピが表示される

なお読み上げには1分以上経ってからにしないとAPIリクエストが多すぎてエラーになるので注意

不要な情報(価格、電話番号、住所、営業時間など)を取り除き、食材に焦点を当ててレシピを提案します。
鶏むね肉と夏野菜の炒め物
材料:
* 鶏むね肉 (100g):一口大に切る
* トウモロコシ:実を外す
* ピーマン (1パック):種を取り、細切りにする
* トマト (1パック):くし切りにする
* キュウリ (1パック):薄切りにする
* 旬彩盛 (1パック):内容に応じて適当な大きさに切る (例:もやしならそのまま、ニラなら3cm程度に切る)
* サラダ油:大さじ1
* 塩コショウ:少々
* 醤油:小さじ1
* 酒:小さじ1
* 鶏ガラスープの素:小さじ1/2
作り方:
1. フライパンにサラダ油を熱し、鶏むね肉を炒める。
2. 鶏肉の色が変わったら、ピーマン、キュウリ、旬彩盛を加えて炒める。
3. 野菜がしんなりしてきたら、トウモロコシ、トマトを加えて軽く炒める。
4. 塩コショウ、醤油、酒、鶏ガラスープの素で調味する。
5. 全体に味がなじんだら、火を止めて完成。
うなぎと野菜の丼
材料:
* うなぎ (1串):温める
* ピーマン (1パック):千切りにする
* キュウリ (1パック):千切りにする
* トマト (1パック):薄切りにする
* 温かいご飯:適量
* 刻み海苔:適量
作り方:
1. 温かいご飯を丼によそう。
2. ピーマン、キュウリ、トマトを丼に盛り付ける。
3. うなぎを乗せる。
4. 刻み海苔を散らして完成。
国産牛ロースのミニステーキ
材料:
* 国産牛ロース (100g):軽く塩コショウを振る
* サラダ油:小さじ1
* 醤油:小さじ1/2
* わさび:お好みで
作り方:
1. フライパンにサラダ油を熱し、牛ロースを焼く。
2. 片面1~2分ずつ焼き、焼き加減を調整する。
3. 醤油を回し入れて香りを出す。
4. 皿に盛り付け、お好みでわさびを添えて完成。
これらのレシピは、提示された少ない食材で簡単に作れるものです。旬彩盛の内容がわからないため、具体的な調理法は示していませんが、他の野菜と同様に炒めたり、丼に添えたりできます。 必要に応じて、他の調味料や食材を追加してアレンジしてみてください。

この内容の長さでも pyttxs なら macなら読み上げ可能

Ubuntuだと音源がないのでできないので
別のものを試す

チラシの解析(gemini)

チラシの解析(gemini)

【AI × チラシ解析】忙しい社会人のための“節約レシピ提案アプリ”を作ってみた

がまさに答えっぽい

touch image_analysis.py

でファイルを作成

イメージは.pngなので
これを読み込むようにする

from google import genai
from PIL import Image

class Gemini:
    def __init__(self):
        API_KEY = "生成したAPIキー"
        self.model = "gemini-2.0-flash"
        self.client = genai.Client(api_key=API_KEY)
        self.prompt = "スーパーマーケットの広告画像です。それぞれの広告に掲載されている商品と価格を”全て”抽出してリストにしてください。また掲載されている食材を使った今晩のレシピを提案してください。その際、1人前のおおよその価格も計算して教えてください。なお、調味料や米などは自由に使えるものとします。"

    def loadImage(self):
        # スクレイピングした画像データをロード
        image_paths = glob.glob("./source/*.jpg")
        images = []
        for image_path in image_paths:
            images.append(Image.open(image_path))
        self.images = images

    def run(self,prompt="",image=""):
        prompt = self.prompt
        images = self.images

        response = self.client.models.generate_content(
            model=self.model
            ,contents=[images,prompt]
        )
        self.response = response.text
        print(self.response)

が参考もとコード

これを商品リストのみに変更する

mkdir source
cp step-1.png source 

でファイルを移動

実行したら

Traceback (most recent call last):
  File "/Users/snowpool/aw10s/gemini/image_analysis.py", line 1, in <module>
    from google import genai
ImportError: cannot import name 'genai' from 'google' (unknown location)

となった

どうやらインポートの文が間違いらしい

これを

import google.generativeai as genai

としたけど動作しない

Mainの記述がないで

if __name__ == "__main__":
    gemini = Gemini()
    gemini.loadImage()
    gemini.run()

を追加したが

python image_analysis.py
Traceback (most recent call last):
  File "/Users/snowpool/aw10s/gemini/image_analysis.py", line 34, in <module>
    gemini = Gemini()
             ^^^^^^^^
  File "/Users/snowpool/aw10s/gemini/image_analysis.py", line 9, in __init__
    self.client = genai.Client(api_key=API_KEY)
                  ^^^^^^^^^^^^
AttributeError: module 'google.generativeai' has no attribute 'Client'

となった

Google の google-generativeai ライブラリには Client というクラスは存在しません
とのこと

以下のように genai.configure() を使い、GenerativeModel を直接生成
gemini-2.0-flash → テキスト特化(画像には非対応)
gemini-pro-vision → 画像入力に対応 ✅

ということなので

import glob
from PIL import Image
import google.generativeai as genai

class Gemini:
    def __init__(self):
        API_KEY = "AIzaSyBGtutzF_xdEWcPf8343jyAt_Qq3t1cFIQ"  # セキュアな方法で管理を推奨
        genai.configure(api_key=API_KEY)

        # モデルを設定(画像対応モデルは gemini-pro-vision)
        self.model = genai.GenerativeModel("gemini-pro-vision")
        self.prompt = "スーパーマーケットの広告画像です。それぞれの広告に掲載されている商品と価格を”全て”抽出してリストにしてください。"

    def loadImage(self):
        # ./source/*.png を取得
        image_paths = glob.glob("./source/*.png")
        if not image_paths:
            print("⚠️ 画像が見つかりません")
        self.images = [Image.open(path) for path in image_paths]

    def run(self):
        for idx, image in enumerate(self.images):
            print(f"🖼 画像{idx+1} を処理中...")
            try:
                response = self.model.generate_content(
                    [self.prompt, image],
                    stream=False
                )
                print("✅ 結果:")
                print(response.text)
            except Exception as e:
                print("⚠️ エラー:", e)

# 実行用ブロック
if __name__ == "__main__":
    gemini = Gemini()
    gemini.loadImage()
    gemini.run()

としたが

🖼 画像1 を処理中...
⚠️ エラー: 404 Gemini 1.0 Pro Vision has been deprecated on July 12, 2024. Consider switching to different model, for example gemini-1.5-flash.
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:1745014048.933884 7409777 init.cc:232] grpc_wait_for_shutdown_with_timeout() timed out.

gemini-1.5-pro-vision
にしても

🖼 画像1 を処理中...
⚠️ エラー: 404 models/gemini-1.5-pro-vision is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods.
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:1745014171.856705 7412024 init.cc:232] grpc_wait_for_shutdown_with_timeout() timed out.

ということで使用するモデルバージョンを変更

import glob
from PIL import Image
import google.generativeai as genai

class Gemini:
    def __init__(self):
        API_KEY = "AIzaSyBGtutzF_xdEWcPf8343jyAt_Qq3t1cFIQ"  # セキュアな方法で管理を推奨
        genai.configure(api_key=API_KEY)

        # モデルを設定(画像対応モデルは gemini-pro-vision)
        self.model = genai.GenerativeModel("gemini-1.5-pro")
        self.prompt = "スーパーマーケットの広告画像です。それぞれの広告に掲載されている商品と価格を変更せずに”全て”抽出してリストにしてください。"

    def loadImage(self):
        # ./source/*.png を取得
        image_paths = glob.glob("./source/*.png")
        if not image_paths:
            print("⚠️ 画像が見つかりません")
        self.images = [Image.open(path) for path in image_paths]

    def run(self):
        for idx, image in enumerate(self.images):
            print(f"🖼 画像{idx+1} を処理中...")
            try:
                response = self.model.generate_content(
                    [self.prompt, image],
                    stream=False
                )
                print("✅ 結果:")
                print(response.text)
            except Exception as e:
                print("⚠️ エラー:", e)

# 実行用ブロック
if __name__ == "__main__":
    gemini = Gemini()
    gemini.loadImage()
    gemini.run()

として実行すると

✅ 結果:
リストは以下の通りです。

* カップヌードル:125円
* 柔軟剤:699円
* 冷凍食品:109円
* ポカリスエット:329円
* キリンレモン:459円
* お茶漬け:179円
* 大人用オムツ:299円
* ミックスナッツ:329円
* 牛乳:299円
* ドレッシング:249円
* 救急バン:169円
* フェイスマスク:99円
* 豆乳飲料:259円
* ティッシュペーパー:399円
* ハーゲンダッツ:199円
* 海苔:199円
* 食パン:89円
* ウェットティッシュ:99円
* バナナ:139円
* 卵:128円
* ポテトチップス:159円
* ベーコン:89円
* プチトマト:299円
* キュウリ:249円
* サラダチキン:299円
* 豆腐:369円
* ヨーグルト:179円
* 冷凍うどん:848円
* 冷凍食品:880円
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:1745015805.274105 7441488 init.cc:232] grpc_wait_for_shutdown_with_timeout() timed out.

元々のプロンプトは

        self.prompt = "スーパーマーケットの広告画像です。それぞれの広告に掲載されている商品と価格を”全て”抽出してリストにしてください。"

これだと

🖼 画像1 を処理中...
✅ 結果:
画像に掲載されている商品と価格のリストです。

* カップ麺:109円
* ドリンク:30円/329円
* 食パン:125円/249円
* 殺虫剤:50円/699円
* ポカリスエット:150円/459円
* 鶏肉:179円/329円
* 牛乳:299円
* ペン:20円/249円
* 救急バン:169円/119円
* パック飲料:10円/299円
* シャンプー:259円/399円
* ハーゲンダッツ:250円/199円
* 緑茶:199円
* トイレットペーパー:89円
* 卵:99円
* バナナ:139円/128円
* 豆腐:159円
* 納豆:89円
* 油揚げ:299円
* ヨーグルト:249円
* みかん:299円/369円
* ソーセージ:179円/848円
* ハム:880円

gemini でのスクショの撮影

プロンプトを

https://www.shufoo.net/pntweb/shopDetail/860323/?cid=nmail_pcへアクセスし、「日替」と書かれた画像をクリックした後に「プリント」をクリックし
送信先から「PDFに保存」を選択して「保存」をクリックしてください。

だと
プリント画面で固まる
おそらくプリントの部分がbrowserではないため制御外になると思う

なのでフルスクリーンにしてスクショ
が正解っぽい

スクショに関しては
https://zenn.dev/gunjo/articles/2f6898b846d371

https://zenn.dev/kbyk/articles/3e997a2f762018
を参考に進める

以下コード

from langchain_google_genai import ChatGoogleGenerativeAI
from browser_use import Agent
from browser_use.browser.browser import Browser, BrowserConfig
from browser_use.controller.service import Controller

import asyncio

controller = Controller()
agent = None

@controller.registry.action('スクリーンショットを保存する')
async def save_screenshot(filename: str = "screenshot.png") -> str:
    page = await agent.browser_context.get_current_page()
    await page.screenshot(path=filename)
    return f"スクリーンショットを {filename} として保存しました"
    
async def main():
    global agent
    llm = ChatGoogleGenerativeAI(model="gemini-pro")  # Gemini Pro モデルを指定
    agent = Agent(
        task="""
        以下の手順を実行してください:
        1. https://s.shufoo.net/chirashi/860323/?cid=nmail_pc にアクセス
        2. 「日替」という画像をクリック
        3. 「フルスクリーン」ボタンをクリック
        4. 拡大画像が表示されたら、スクリーンショットを step-{n}.png として保存
        """,
        llm=llm,
        controller=controller,
        browser=Browser(config=BrowserConfig(
            disable_security=True, 
            headless=False,
        )),
    )
    result = await agent.run()
    print(result)

if __name__ == "__main__":
    asyncio.run(main())

これで実行すると

INFO [browser_use] BrowserUse logging setup complete with level info INFO [root] Anonymized telemetry enabled. See https://github.com/browser-use/browser-use for more information. INFO [agent] 🚀 Starting task: 以下の手順を実行してください: 1. https://s.shufoo.net/chirashi/860323/?cid=nmail_pc にアクセス 2. 「日替」という画像をクリック 3. 「フルスクリーン」ボタンをクリック 4. 拡大画像が表示されたら、スクリーンショットを step-{n}.png として保存 INFO [agent] 📍 Step 1 WARNING [langchain_google_genai.chat_models] Retrying langchain_google_genai.chat_models._achat_with_retry.<locals>._achat_with_retry in 2.0 seconds as it raised NotFound: 404 models/gemini-gemini-2.0-flash-exp is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods.. ERROR [agent] ❌ Result failed 1/3 times: 404 models/gemini-gemini-2.0-flash-exp is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods. INFO [agent] 📍 Step 1 WARNING [langchain_google_genai.chat_models] Retrying langchain_google_genai.chat_models._achat_with_retry.<locals>._achat_with_retry in 2.0 seconds as it raised NotFound: 404 models/gemini-gemini-2.0-flash-exp is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods.. ERROR [agent] ❌ Result failed 2/3 times: 404 models/gemini-gemini-2.0-flash-exp is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods. INFO [agent] 📍 Step 1 WARNING [langchain_google_genai.chat_models] Retrying langchain_google_genai.chat_models._achat_with_retry.<locals>._achat_with_retry in 2.0 seconds as it raised NotFound: 404 models/gemini-gemini-2.0-flash-exp is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods.. ERROR [agent] ❌ Result failed 3/3 times: 404 models/gemini-gemini-2.0-flash-exp is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods. ERROR [agent] ❌ Stopping due to 3 consecutive failures INFO [agent] Created GIF at agent_history.gif AgentHistoryList(all_results=[ActionResult(is_done=False, extracted_content=None, error='404 models/gemini-gemini-2.0-flash-exp is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods.', include_in_memory=True), ActionResult(is_done=False, extracted_content=None, error='404 models/gemini-gemini-2.0-flash-exp is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods.', include_in_memory=True), ActionResult(is_done=False, extracted_content=None, error='404 models/gemini-gemini-2.0-flash-exp is not found for API version v1beta, or is not supported for generateContent. Call ListModels to see the list of available models and their supported methods.', include_in_memory=True)], all_model_outputs=[]) となった

エラーメッセージから、指定した gemini-gemini-2.0-flash-exp というモデルが Google Generative AI API v1beta では見つからない という問題が発生

現在、LangChain で GoogleGenerativeAI を使用する際にサポートされているモデルには以下の
gemini-pro
gemini-pro-vision
gemini-1.5-pro
gemini-1.5-flash
らしい

gemini-1.5-flash
で実験したが
意図しない場所でスクショになってしまう

そもそも見ているページが違っている

https://www.shufoo.net/pntweb/shopDetail/860323/45225639804667/
の挙動を見ていたが

指定しているURLが
メールだと
https://www.shufoo.net/pntweb/shopDetail/860323/?cid=nmail_pc
になっているので

メールからではなく
チラシのURLが動的でないかを調べることにする

なおメールに記載されているURLに関しては固定のままなので
そのまま使えるURLになっている

URLを変更したが、フルスクリーンをクリックした後すぐにスクショだと
フルスクリーン画面になる前に撮影してしまうため
3秒停止とプロンプトに追加したが失敗する

このため

        1. https://www.shufoo.net/pntweb/shopDetail/860323/?cid=nmail_pc にアクセス
        2. 「フルスクリーン」ボタンをクリック後、数秒待機
        3. スクリーンショットを step-{n}.png として保存
        """,

というようにプロンプトを変更することで成功

画像が小さいため

        以下の手順を実行してください:
        1. https://www.shufoo.net/pntweb/shopDetail/860323/?cid=nmail_pc にアクセス
        2. 「フルスクリーン」ボタンをクリック後、数秒待機
        3. フルスクリーン画面が表示されたら、拡大をクリック後、数秒待機
        4. スクリーンショットを step-{n}.png として保存
        """,

とすると今度は拡大のみになる
ブラウザの取り扱いが別のブラウザ扱いなのかもしれない