エラー判定でforループから綺麗に抜ける方法はないものか。。。

[こんなの](https://qiita.com/airtoxin/items/ae1e82d65b8f3d1efbf2)とか見つけたけどどうにも腑に落ちない

# 状況

仕事であるサイトにスクレイピングをかけて、
formに値を挿入し送信ボタンをクリックするというプログラムを書いていた。
その設定の一つにセレクトボックスがある。

```html:hogehoge.html
<select name="hogehoge">
    <option value="8496739173">あああ</option>
    <option value="2910384718">いいい</option>
    <option value="5901974020">ううう</option>
```

3つしか書いていないが実際には100近くある。
これに対して、与えたい設定値がそもそもサイトに存在しなかった場合、
途中でプログラムをストップさせたい。

```python:test.py
for option_tag in Select(driver.find_element_by_name('hogehoge')).options:
    if option_tag.text == arakajime_kimerareta_atai:
        Select(driver.find_element_by_name('hogehoge')).select_by_visible_text(arakajime_kimerareta_atai)
        break
# ここに来た時に1度もif文を通過していなかったらストップさせたい
```

しかしセレクトボックス以外にもテキストエリアやチェックボックスなど様々な要素がある。
それらも全て設定をしたい。

これに対して現在以下の4通りのアイディアを考えたが、
どれもこれも妙にしっくりこないので、
何かアイディアを持っている方がいらっしゃったら**ご教授願いたい**。

ちなみに、


 - gotoの使用はCTOに却下された
 - valueは何が入っているかあらかじめ分からないため使用できない

# その1　フラグを持たせる

```python:test1.py
is_selected = False
for option_tag in Select(driver.find_element_by_name('hogehoge')).options:
    if option_tag.text == arakajime_kimerareta_atai:
        Select(driver.find_element_by_name('hogehoge')).select_by_visible_text(arakajime_kimerareta_atai)
        is_selected = True
        break
if not is_selected:
    print('There is not select value!!')
    driver.quit()
    exit()
```

いちいち変数を宣言しなくちゃいけないしプログラムも長くなりがち。
4つの中では一番嫌い。

# その2　for文の中に続きの処理を書く

```python:test2.py
for option_tag in Select(driver.find_element_by_name('hogehoge')).options:
    if option_tag.text == arakajime_kimerareta_atai:
        Select(driver.find_element_by_name('hogehoge')).select_by_visible_text(arakajime_kimerareta_atai)

        # ここにテキストエリアとかの処理やボタンクリック、正常終了時の処理を書く

print('There is not select value!!')
driver.quit()
exit()
```

余計な変数の宣言はしなくて済むけどfor内部の処理が多いと不格好になる。

# その3　関数化してreturnで返す
（実際はクラス化してselfつけてあるので引数は不要な環境でやっている）

```python:test3.py
def select_only(driver, arakajime_kimerareta_atai):
    for option_tag in Select(driver.find_element_by_name('hogehoge')).options:
        if option_tag.text == arakajime_kimerareta_atai:
            Select(driver.find_element_by_name('hogehoge')).select_by_visible_text(arakajime_kimerareta_atai)
            return

    print('There is not select value!!')
    driver.quit()
    exit()

select_only(driver, arakajime_kimerareta_atai)
```

まぁ悪くないけどこのためにわざわざ関数用意するのも。。。

# その4　丸ごとテキストを取得して判定する

```python:test4.py
if not arakajime_kimerareta_atai in driver.find_element_by_name('hogehoge').text:
    print('There is not select value!!')
    driver.quit()
    exit()

for option_tag in Select(driver.find_element_by_name('hogehoge')).options:
    if option_tag.text == arakajime_kimerareta_atai:
        Select(driver.find_element_by_name('hogehoge')).select_by_visible_text(arakajime_kimerareta_atai)
        break
```

発想は悪くはないが、冒頭のようなDOMに対して、
arakajime_kimerareta_atai が 'あい' だった場合に誤判定を喰らう。
それを回避するために適当な文字を挟んで連結をさせるのも考えたが、
かえってプログラムが汚くなった。

# 頂いたコメントへのご返信

> shiracamusさん

恥ずかしながらanyとallは初めて知りました。
本件以外にも色々と使えそうですね。
ありがとうございます。

> konandoiruasaさん

for-elseの発想はなかったです。
これが一番しっくりきました。
今回はこれで実装します。
ありがとうございます。

確かにflagは一番シンプルだと思いますが、
どうにも個人的に好きにはなれません。。。

# コメント受けて追記

anyとallをググってはっとしたが、
組み込み関数に対する知識が不十分だと気付いた。
[公式の組み込み関数一覧](https://docs.python.org/ja/3/library/functions.html)

len、list、range、hasattr、type、zipあたりは
業務で日常的に使っていたのである程度知識はあったが、
exec、sorted、evalなどメジャー(に見える)ものも
存在すら知らなかった。

十分にpythonを実践(業務)で使いこなせていると思っていたが、
全くそんなことはなかったことに気づけたのは不幸中の幸いだった。

やはり日々の勉強が大事。
毎日1歩でもいいから前進しようと改めて心に誓った。