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

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

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

Q&A

解決済

1回答

548閲覧

Seleniumで指定の要素だけ新しいタブで開きたいが、他の要素まで新しいタブで開いてしまう

fullmoon311

総合スコア62

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python

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

selenium

Selenium(セレニウム)は、ブラウザをプログラムで作動させるフレームワークです。この原理を使うことにより、ブラウザのユーザーテストなどを自動化にすることができます。

0グッド

0クリップ

投稿2022/09/14 07:03

編集2022/09/14 07:32

前提

下記のような作りのサイトで、最終的に表示される値をスクレイピングしcsvに出力する処理を実装しています。

イメージ説明
イメージ説明
イメージ説明

「入力内容を確認する」ボタンクリックで、新しいタブで開くことが出来ましたが、
そのあとの「結果を見る」ボタンまでもが新しいタブで開いてしまいます。

現状では1行も取得できずcsvは書き込まれていません。

これだとすべての値が取得されず、全部の値がcsvに書き込まれません。

恐らく、
actions = ActionChains(driver)
をしているからすべての要素でもコントロールキー押されながらクリックされるためです。

「入力内容を確認する」ボタンのクリックで新しいタブで開いて値を取得すれば
for文が途中でエラーにならず全部の値が取得できると思っています。

ソースコードをすべて載せます。
よろしくお願いします。

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • ▲▲機能を動作するようにする

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

python

1 2from selenium import webdriver 3from selenium.webdriver.common.keys import Keys as keys 4from selenium.webdriver.support.select import Select 5from selenium.webdriver.common.by import By 6from selenium.webdriver.common.action_chains import ActionChains 7from selenium.webdriver.support.ui import WebDriverWait 8from selenium.webdriver.common.keys import Keys 9import platform 10import sys 11from selenium.common.exceptions import TimeoutException 12 13driver = webdriver.Chrome(executable_path="C:\chromedriver.exe") 14 15# 1.動的サイトにアクセス 16driver.get("https://xxxxx.com/") 17 18# クリック前のハンドルリスト 19handles_befor = driver.window_handles 20 21# ドロップダウンを選択する 22genres = driver.find_element(By.ID,'Genre') 23select = Select(genres) 24all_options = select.options 25count = len(all_options) 26 27for n in range(count): 28 if(n != 0): 29 Select(genres).select_by_index(n) 30 makers = driver.find_element(By.ID,'Maker') 31 select2 = Select(makers) 32 all_options2 = select2.options 33 count2 = len(all_options2) 34 for m in range(count2): 35 if(n!=0 and m != 0): 36 Select(makers).select_by_index(m) 37 models = driver.find_element(By.ID,'ModelName') 38 select3 = Select(models) 39 all_options3 = select3.options 40 count3 = len(all_options3) 41 for x in range(count3): 42 if(n!=0 and m !=0 and x!=0): 43 Select(models).select_by_index(x) 44 if(n == 1): 45 m_years = driver.find_element(By.ID, 'ModelYear') 46 select4 = Select(m_years) 47 all_options4 = select4.options 48 count4 = len(all_options4) 49 for y in range(count4): 50 if(n!=0 and m !=0 and x!=0 and y!=0): 51 Select(m_years).select_by_index(y) 52 # 年式が選択されたら「確認する」ボタンを押す&新しいタブで開く 53 element = driver.find_element(By.ID,'submittrial') 54 #(リンク)要素を新しいタブで開く 55 actions = ActionChains(driver) 56 57 if platform.system() == 'Darwin': 58 #Macなのでコマンドキー 59 actions.key_down(Keys.COMMAND) 60 else: 61 #Mac以外なのでコントロールキー 62 actions.key_down(Keys.CONTROL) 63 actions.click(element) 64 actions.perform() 65 #新しいタブが開ききるまで最大10秒待機 66 try: 67 WebDriverWait(driver, 10).until(lambda a: len(a.window_handles) > len(handles_befor)) 68 except TimeoutException: 69 print('TimeoutException: 新規ウィンドウが開かずタイムアウトしました') 70 sys.exit(1) 71 #クリック後のハンドルリスト 72 handles_after = driver.window_handles 73 #ハンドルリストの差分 74 handle_new = list(set(handles_after) - set(handles_befor)) 75 #新しいタブに移動 76 driver.switch_to.window(handle_new[0]) 77         78 # 「結果を見る」ボタンを押す ※ここで新しいタブ開いてしまう※ 79 80 driver.find_element(By.XPATH,'//*[@id="AsmtCycleTConfirmForm"]/div[2]/button[2]').click() 81 # 表示された値を取得 82 # 1.査定価格, 2.ジャンル, 3.メーカー, 4.モデル, 5.品番, 6.モデル年式 83 val1 = driver.find_element(By.XPATH, '/html/body/div/div[2]/div[2]/p[1]/span').text 84 # 査定価格の¥マークと全角スペースをトリム 85 val1 = val1.replace('¥','') 86 val1 = str.strip(val1) 87 val2 = driver.find_element(By.XPATH,'/html/body/div/div[3]/table/tbody/tr[1]/td').text 88 val3 = driver.find_element(By.XPATH, '/html/body/div/div[3]/table/tbody/tr[2]/td').text 89 val4 = driver.find_element(By.XPATH,'/html/body/div/div[3]/table/tbody/tr[3]/td').text 90 val5 = driver.find_element(By.XPATH,'/html/body/div/div[3]/table/tbody/tr[4]/td').text 91 val6 = driver.find_element(By.XPATH, '/html/body/div/div[3]/table/tbody/tr[5]/td').text 92 # 値を,区切りで結合 93 val_low = val1 + ', ' + val2 + ', ' + val3 + ', ' + val4 + ', ' + val5 + ', ' + val6 94 # csvファイルに保存 95 filename = "kekka.csv" 96 with open(filename, mode="a", encoding="utf-8", newline='\n') as f: 97 f.write(val_low) 98 99 100

追記1

actions.reset_actions()
をしたら、新しいタブは開かず処理は実行されそのスレッドのcsvは書き込まれましたが、
次のfor文に戻ったときにその画面が開いたまままなので
csv書き込まれてたら新しいタブは閉じる処理をしたらよいでしょうか?

追記2

csv書き込んだ後最後にdriver.close()をしてみたところ、新しく閉じたタブは閉じられましたが
(元の画面は残っています)
for文に戻ったらすでに閉じられたとErrorになりました。
新しく開いたタブに対してcloseはどう指定したらよいですか?
ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

自己解決

自己解決いたしました。
最後、
driver.close()
driver.switch_to.window(handles_after[0])
としたら動作しました。

投稿2022/09/14 11:03

fullmoon311

総合スコア62

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問