質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1287閲覧

Python エラー処理を検知しエクセルのデータを追加したい

fideo

総合スコア55

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/09/21 06:21

編集2021/09/24 08:19

Python3とSelenium, openpyxlを使ってExcelのデータを読み込みYahoo! 乗換案内の検索をしています。

各駅を検索したらExcelのD列に処理済みの結果を記載しています。
WEB上で検索できない場合、
エラーが表示されたらループを抜けて、次のループに(日暮里)進み
下記のようにフラグに処理済みのデータを記載したいです。
エラーした場合処理済みのフラグを記載しないようにしたいです。

Excelデータ(実現内容)

No駅2フラグ
1東京品川処理済み
2原宿原宿
3日暮里秋葉原処理済み
4東京原宿処理済み
5池袋@@@
tryでWEB側でエラーを検知して下記のコードに入れてみましたが、 実現したい処理と上手く処理できず、 全てのデータに処理済みと記載されます。 ifには検索後にタイトルを取得すれば処理済みのフラグを記載するように組みました。 eleseのようにエラーしたら処理済みを記載しないようにプログラムを記載 しましたが何故か全てのデータに処理済みと記載されます。 ご指導をお願いできますでしょうか。 try:#タイトルを取得 message = driver.find_element_by_xpath('//*[@id="cat-pass"]').text print(message) #Print結果:路線情報トップ > ルート、運賃検索結果 except: print("error") if "路線情報トップ > ルート、運賃検索結果"== message: # 処理済みのでデータをD列へ入力 df.loc[i,'フラグ']='処理済み' print("処理済み・書込み") #EXCEL保存 df.to_excel("test.xlsx", header=False, index=False) else: print("エクセルへフラグ記載しない") Excelデータ(現在の結果) |No | 駅 | 駅2 |フラグ| |-----:|:---------|:---------------|---------------| |1 | 東京 |品川|処理済み| |2 | 原宿 | 原宿 |処理済み| |3 | 日暮里 | 秋葉原|処理済み| |4 | 東京 | 原宿|処理済み| |5 | 池袋 | @@@ |処理済み
# Excel用ライブラリ読込 import openpyxl from selenium.webdriver.common.keys import Keys import time from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.select import Select from selenium import webdriver from selenium.common.exceptions import NoSuchElementException import pyautogui import pandas as pd # Excelファイルを開く v_wb = openpyxl.load_workbook("test.xlsx") # アクティブなシートを変数へ v_ws = v_wb.active # シートのロード ws = v_wb.worksheets[0] # convert to pandas dataframe df = pd.DataFrame(ws.values) print("test") print(df) # generate search words # sort=False データソートせずにエクセル順番で行う lst = df.iloc[0:,1:].values print(lst) df['フラグ'] = '' URL = "https://transit.yahoo.co.jp/" # ブラウザを開く。 #options=option background options = Options() options.add_experimental_option('detach', True) driver = webdriver.Chrome(executable_path="C:\Program Files\chromedriver_win32\chromedriver.exe", options=options) #ループ処理の部分とエクセルへの書き込み処理(行)が合っていないので、 #row = 1を追加 for i, query in enumerate(lst): # Googleの検索TOP画面を開く。 if i > 0: driver.execute_script('window.open()') driver.switch_to.window(driver.window_handles[i]) driver.get(URL) # 2秒待機 time.sleep(2) # from fromid = driver.find_element_by_name("from") fromid.send_keys(query[0]) # to to = driver.find_element_by_name("to") to.send_keys(query[1]) #search time.sleep(2) pyautogui.press(['enter']) try:#タイトルを取得 message = driver.find_element_by_xpath('//*[@id="cat-pass"]').text print(message) #Print結果:路線情報トップ > ルート、運賃検索結果 except: print("error") if "路線情報トップ > ルート、運賃検索結果"== message: # 処理済みのでデータをD列へ入力 df.loc[i,'フラグ']='処理済み' print("処理済み・書込み") #EXCEL保存 df.to_excel("test.xlsx", header=False, index=False) else: print("エクセルへフラグ記載しない")

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2021/09/21 06:41

> ただ同じ駅だったら乗換案内で下記のエラーメッセージが表示されます。 同じ駅ならスクレイピングの処理自体をスキップした方が良いのではないでしょうか?
fideo

2021/09/21 07:38 編集

回答ありがとうございます。スキップできますがただまた駅以外に5行目のように池袋と@@ 検索すると別のエラーが表示されます。 WEB側でエラーしたら例外で処理し,正常のみ処理済みと記載したいです。可能でしょうか。
meg_

2021/09/21 08:31

処理はtryの中に全て書けば良いのでは?
fideo

2021/09/21 09:01

回答ありがとうございます。早速やってみたところですが、上記のように エラーした箇所に処理済みのフラグが記載されます。逆に正常に終了したものに記載したいですが、可能でしょうか。ご確認をお願い致します。
meg_

2021/09/21 12:28

> df.loc[(df[1] == query[0]), 'フラグ'] = "処理済み" 上記がtryの中にないからではないですか?
fideo

2021/09/22 00:20 編集

回答ありがとうございます。 tryの中に入れましたら処理済みのフラグが記載されないです。ご確認をお願い致します。
meg_

2021/09/22 00:50

質問のコードですと、for,try,except,elseが同じインデントに見えますが実際のコードも同じですか? また、「> df.loc[(df[1] == query[0]), 'フラグ'] = "処理済み"」のdf[1] == query[0]は意図した条件ですか?
fideo

2021/09/22 01:01 編集

早速返事ありがとうございます。 質問のコードですと、for,try,except,elseが同じインデントに見えますが実際のコードも同じですか? >はい、同じです。 df.loc[(df[1] == query[0]), 'フラグ'] = "処理済み"」のdf[1] == query[0]は意図した条件ですか? >処理済みのデータをD列に入力したので、上記の条件を作成しました。
meg_

2021/09/22 01:51

確認です。 「df.loc[(df[1] == query[0]), 'フラグ'] = "処理済み"」をtryの中に入れる前は、"2 原宿 原宿"と"5 池袋 @@@"の処理済み列に "処理済み"が入力されたのですね?(最後の画像を参照)
fideo

2021/09/22 02:51 編集

回答ありがとうございます。ただ下記の方法で行うと同じ駅と'@@@'でエラーした場合 回避できると思いますが、WEB側上で別のエラーが表示されても対応できるようにしたいです。例;NoSuchElementExceptionが見つからない時とかであればどのエラーでも回避できると思います。
fideo

2021/09/22 02:43

分かりにくい質問で申し訳ありませんでした。質問内容を修正いたしました。selenium.common.exceptions.NoSuchElementException: Message: no such element: のエラーが表示されたらエラー処理を検知しエクセルのデータを追加したいです。
fideo

2021/09/22 07:18

度々、すいません。 午前中で回答してもらった方法で上手くいけそうですが、 下記のように行いましたが、 print('エラー')4回表示されます。 希望通りの操作にするにはどのようにすればよろしいでしょうか。 ご確認をお願い致します。 for i, query in enumerate(lst): # Googleの検索TOP画面を開く。 if i > 0: driver.execute_script('window.open()') driver.switch_to.window(driver.window_handles[i]) driver.get(URL) # 2秒待機 time.sleep(2) # from fromid = driver.find_element_by_name("from") fromid.send_keys(query[0]) # to to = driver.find_element_by_name("to") to.send_keys(query[1]) #search time.sleep(2) pyautogui.press(['enter']) for i, query in enumerate(lst): try: cheap = driver.find_element_by_xpath('//*[@id="tabflt"]/li[3]/a').text # print(cheap) if df.iloc[i,0]!=df.iloc[i,1] : # print(cheap) df.loc[i,'フラグ']='処理済み' else: raise ValueError except: print('エラー') df.to_excel("test.xlsx", header=False, index=False) for i, query in enumerate(lst): # Googleの検索TOP画面を開く。 if i > 0: driver.execute_script('window.open()') driver.switch_to.window(driver.window_handles[i]) driver.get(URL) # 2秒待機 time.sleep(2) # from fromid = driver.find_element_by_name("from") fromid.send_keys(query[0]) # to to = driver.find_element_by_name("to") to.send_keys(query[1]) #search time.sleep(2) pyautogui.press(['enter']) for i, query in enumerate(lst): try: cheap = driver.find_element_by_xpath('//*[@id="tabflt"]/li[3]/a').text # print(cheap) if df.iloc[i,0]!=df.iloc[i,1] : # print(cheap) df.loc[i,'フラグ']='処理済み' else: raise ValueError except: print('エラー') df.to_excel("test.xlsx", header=False, index=False)
meg_

2021/09/22 11:37

raise ValueErrorの部分はテストコードのために書いたものなので、実際のコードには不要です。
fideo

2021/09/24 03:55

回答ありがとうございます。下記のようにraise ValueErrorの部分はテストコードを消しましたが、 同じく希望通りの操作にならないです。 またデータ何も保存できないです。 もし可能であればもう少し詳しく教えていただけますか。 お手数ですが、よろしくお願い致します。 for i, query in enumerate(lst): # Googleの検索TOP画面を開く。 if i > 0: driver.execute_script('window.open()') driver.switch_to.window(driver.window_handles[i]) driver.get(URL) # 2秒待機 time.sleep(2) # from fromid = driver.find_element_by_name("from") fromid.send_keys(query[0]) # to to = driver.find_element_by_name("to") to.send_keys(query[1]) #search time.sleep(2) pyautogui.press(['enter']) for i, query in enumerate(lst): try: cheap = driver.find_element_by_xpath('//*[@id="tabflt"]/li[3]/a').text # print(cheap) if df.iloc[i,0]!=df.iloc[i,1] : # print(cheap) df.loc[i,'フラグ']='処理済み' except: print('エラー') df.to_excel("test.xlsx", header=False, index=False)
meg_

2021/09/24 09:14

if "路線情報トップ > ルート、運賃検索結果"== message: をelse:に変えて、else: print("エクセルへフラグ記載しない")は削除します。 また、df.to_excel("test.xlsx", header=False, index=False) はforループを抜けた後に一回だけ実行すれば良いと思います。 ※エラーが発生した際もmessageは前回の値を持ってませんか?
fideo

2021/09/25 00:49

ありがとうございます。上記の方法できました。 因みにIF必要ないのは、exceptが手前にあるからでしょうか。
meg_

2021/09/25 01:40

エラー発生したらelse:は実行されないです。 それから「if "路線情報トップ > ルート、運賃検索結果"== message:」では条件分岐できていないので「全てのデータに処理済みと記載されます。」となったのでは?(message = driver.find_element_by_xpath('//*[@id="cat-pass"]').textの前にmessage=''とか書けば前のコードでも動作したかもしれませんが、シンプルなコードの方が良いかとは思います)
fideo

2021/09/27 08:28

説明ありがとうございます。現在問題なく利用できます。
guest

回答1

0

ベストアンサー

try節にdf.loc[i,'フラグ']='処理済み' を書けば所望の結果になるかと思います。

下記データフレームと簡単なコードで試した結果です。

0 1 0 東京 品川 1 原宿 原宿 2 日暮里 秋葉原 3 東京 原宿 4 池袋 @@@

python

1for i, query in enumerate(lst): 2 try: 3 if df.iloc[i,0]!=df.iloc[i,1] and df.iloc[i,1]!='@@@': 4 df.loc[i,'フラグ']='処理済み' 5 else: 6 raise ValueError 7 except: 8 print('エラー') 9 10# 0 1 11#0 東京 品川 処理済み 12#1 原宿 原宿 13#2 日暮里 秋葉原 処理済み 14#3 東京 原宿 処理済み 15#4 池袋 @@@

投稿2021/09/22 02:17

編集2021/09/22 02:23
meg_

総合スコア10607

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問