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

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

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

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

Chrome

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

Python 3.x

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

selenium

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

PyCharm

エディター・開発ツール

Q&A

1回答

2772閲覧

Selenium のスクレイピングでのWebDriverException: Message: no such execution context エラーについて

nomurin

総合スコア0

スクレイピング

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

Chrome

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

Python 3.x

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

selenium

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

PyCharm

エディター・開発ツール

0グッド

0クリップ

投稿2023/09/11 02:25

実現したいこと

yahoo知恵袋の質問文をスクレイピングし、csvに格納する。

前提

ここに質問の内容を詳しく書いてください。
pythonでスクレイピングをできるプログラムを作成中です。
質問文の取得は途中まではできるのですが、
途中でとまって(止まるタイミングもランダム)以下のエラーメッセージが発生しています。

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

質問数に関しては気にしないでください、

['約146', '中1~10', '目'] 約146 質問番号 1 質問番号 2 質問番号 3 質問番号 4 質問番号 5 質問番号 6 質問番号 7 Traceback (most recent call last): File "C:\Users\kusph\PycharmProjects\pythonProject1\main.py", line 105, in <module> browser.back() File "C:\Users\kusph\AppData\Local\Programs\Python\Python311\pythonproject\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 547, in back self.execute(Command.GO_BACK) File "C:\Users\kusph\AppData\Local\Programs\Python\Python311\pythonproject\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 344, in execute self.error_handler.check_response(response) File "C:\Users\kusph\AppData\Local\Programs\Python\Python311\pythonproject\Lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 229, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.WebDriverException: Message: no such execution context (Session info: chrome=117.0.5938.48) Stacktrace: GetHandleVerifier [0x00007FF6E6AC7B82+55138] (No symbol) [0x00007FF6E6A378A2] (No symbol) [0x00007FF6E68ED95D] (No symbol) [0x00007FF6E68DC5B9] (No symbol) [0x00007FF6E68DA961] (No symbol) [0x00007FF6E68DB2EE] (No symbol) [0x00007FF6E68E7D4D] (No symbol) [0x00007FF6E68F8541] (No symbol) [0x00007FF6E68FC87A] (No symbol) [0x00007FF6E68DB937] (No symbol) [0x00007FF6E68F81D3] (No symbol) [0x00007FF6E6967919] (No symbol) [0x00007FF6E694E903] (No symbol) [0x00007FF6E6923711] (No symbol) [0x00007FF6E6924954] GetHandleVerifier [0x00007FF6E6E2C5D2+3613106] GetHandleVerifier [0x00007FF6E6E82450+3964976] GetHandleVerifier [0x00007FF6E6E7AAAF+3933839] GetHandleVerifier [0x00007FF6E6B631F6+691670] (No symbol) [0x00007FF6E6A424E8] (No symbol) [0x00007FF6E6A3E714] (No symbol) [0x00007FF6E6A3E842] (No symbol) [0x00007FF6E6A2EEB3] BaseThreadInitThunk [0x00007FF83C23257D+29] RtlUserThreadStart [0x00007FF83D9CAA68+40]

該当のソースコード

import time import pandas as pd from selenium import webdriver from selenium.common import NoSuchElementException, TimeoutException from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC, wait from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service as ChromeService from selenium.webdriver.chrome import service as fs from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait options = Options() # Chrome Betaのバイナリファイルへのパスを設定 chrome_beta_path = 'C:/Program Files/Google/Chrome Beta/Application/chrome.exe' # Chrome Beta用のオプションを設定 chrome_options = webdriver.ChromeOptions() chrome_options.binary_location = chrome_beta_path # Chrome BetaのWebDriverを起動 chrome_service = ChromeService(executable_path='C:/Users/kusph/chromedriver-win64/chromedriver.exe') browser = webdriver.Chrome(service=chrome_service, options=chrome_options) browser.maximize_window() url = 'https://chiebukuro.yahoo.co.jp/search?p=%E9%9B%AA%E8%A6%8B%E5%A4%A7%E7%A6%8F&vaop=a&search=all&flg=3&dflg=4&dfrom_y=2021&dfrom_m=04&dfrom_d=01&dto_y=2023&dto_m=09&dto_d=11&noct=1' # URLを開く browser.get(url) # リンク一覧を格納するリストを準備 elem_urls = [] elem_dates = [] elem_texts = [] # while で find_element_by_link_text が breakするまでループ num=0 while True: elems = browser.find_elements(By.CLASS_NAME,'ListSearchResults_listSearchResults__heading__1T_RX') dates = browser.find_elements(By.CSS_SELECTOR, '.ListSearchResults_listSearchResults__informationDate__10t00') all= browser.find_element(By.XPATH,'/html/body/div/div/div/div/div[2]/div[1]/div[6]/p') print(all.text.split('件')) all_split=all.text.split('件') print(all_split[0]) for i in range(len(elems)): elem = browser.find_elements(By.CLASS_NAME,'ListSearchResults_listSearchResults__heading__1T_RX')[i] date = browser.find_elements(By.CSS_SELECTOR, '.ListSearchResults_listSearchResults__informationDate__10t00')[i] elem_urls.append(elem.get_attribute("href")) elem_dates.append(date.text) elem.click() num=num+1 time.sleep(7) try: question = browser.find_element(By.CSS_SELECTOR, 'div.ClapLv2QuestionItem_Chie-QuestionItem__Text__1AI-5') question_text = question.text elem_texts.append(question_text) print('質問番号', num) except Exception as e: print('質問の取得に失敗しました:',e) browser.switch_to.default_content() browser.back() time.sleep(5) scroll_script = "window.scrollTo(0, document.body.scrollHeight);" browser.execute_script(scroll_script) time.sleep(3) # ページ遷移後に少し待機して次の要素を取得 # 現在のページのURLを取得 current_page_url = browser.current_url data = { 'URL': elem_urls, '日にち': elem_dates, '質問': elem_texts } df = pd.DataFrame(data) # DataFrameをエクセルファイルに書き込み file_path = 'C:/Users/kusph/Desktop/output.xlsx' with pd.ExcelWriter(file_path,engine='openpyxl', mode='a', if_sheet_exists='replace') as writer: df.to_excel(writer, sheet_name='sheet11', index=False) print('質問数:', len(elem_urls)) try: next_button = browser.find_element(By.PARTIAL_LINK_TEXT, '次へ') next_button.click() time.sleep(3) except Exception as e: # 次へボタンが見つからない場合、プログラムを終了する print('次へボタンが見つかりませんでした。スクレイピングを終了します。') browser.quit() break wait = WebDriverWait(browser, 10) wait.until(EC.url_changes(current_page_url)) browser.quit()

試したこと

・chrome β版の最新VERに変更。
・timeで待機時間を多く設ける。

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

Python 3.11.4
chrome=117.0.5938.48
selenium 4.8.3

ずっとこのエラーで止まっています、、助けてください、、

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

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

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

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

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

guest

回答1

0

問題点

iframe に対する操作がないのに、最初のフレームにフォーカスを戻す browser.switch_to.default_content() が、使用されています。

加えて、コードは以下のような流れで構成されていますが:

  1. 検索結果の総数を取得して表示する

  2. 各質問へのリンク(URL)と更新日時を取得して、リストに格納する

  3. 各質問へのリンクをクリックして、質問ページを開き、本文を取得する

  4. ブラウザバックを利用して、前の一覧ページに戻る

  5. 再度、一覧ページでリンクと日付を取得し、次の質問にアクセスする

  6. 1-5 を繰り返す

  7. 取得した情報を整理してエクセルファイルに書き込む

  8. 次の一覧ページへ遷移する

  9. 1-8 を繰り返す

  • 5 で、無駄な処理(リンクと日付を取得)が繰り返されています。繰り返しが必要なのは、3 と 4 だけです。

  • 7 のエクセルファイルへの書き出しが、ループ内で実行されています。

  • また、4 のブラウザバックを繰り返す行為は効率が悪いので、あとでまとめてアクセスした方がいいです。

改善案

コードを以下のような流れに書き換えます。

  1. 検索結果の総数を取得して表示する

  2. 各質問へのリンク(URL)と更新日時を取得して、リストに格納する

  3. 次の一覧ページへ遷移して、2 の作業を行う

  4. 上記の 2-3 を繰り返して、全ての質問への URL を一つのリストにまとめる

  5. まとめたリストの URL を上から順にアクセスして、質問本文を取得してリストにまとめる

  6. URL、日時、本文が格納されたリストを zip() 関数を利用して一つにまとめる

  7. 整理した情報を CSV で書き出す

  • ポイントは、質問ページの URL の取得と、本文の取得を別の作業として分けるということです。

  • ファイルへの書き出しを最後に持ってくることで、クローリングとスクレイピングをスムーズに実行でき、I/O エラーが発生した場合も柔軟に対応できます。

注意点

質問文が取得できなかった場合、3 つのリストの値の数が一致しないため、不正なデータとなり、CSV や エクセルに書き込めません。

そのため、例外を捉えた際に NA や 「情報を取得できませんでした」といった値を都度リストに追加すべきです。

また、質問文が取得できなかった理由も知りたいので、デバッグ情報として取得できなかった URL も出力するようにしておくといいと思います。

コード例

以上を踏まえて、簡単にコードを書きなおしてみました。動作確認はしていないので悪しからず。

python

1import csv 2import time 3 4from selenium import webdriver 5from selenium.webdriver.chrome.options import Options 6from selenium.webdriver.chrome.service import Service as ChromeService 7from selenium.webdriver.common.by import By 8 9options = Options() 10 11# Chrome Betaのバイナリファイルへのパスを設定 12chrome_beta_path = "C:/Program Files/Google/Chrome Beta/Application/chrome.exe" 13 14# Chrome Beta用のオプションを設定 15chrome_options = webdriver.ChromeOptions() 16chrome_options.binary_location = chrome_beta_path 17 18# Chrome BetaのWebDriverを起動 19chrome_service = ChromeService( 20 executable_path="C:/Users/kusph/chromedriver-win64/chromedriver.exe" 21) 22 23browser = webdriver.Chrome(service=chrome_service, options=chrome_options) 24 25browser.maximize_window() 26 27# ページ遷移後すぐに要素が見つからない場合に待機する時間の設定 28browser.implicitly_wait(10) 29 30url = "https://chiebukuro.yahoo.co.jp/search?p=%E9%9B%AA%E8%A6%8B%E5%A4%A7%E7%A6%8F&vaop=a&search=all&flg=3&dflg=4&dfrom_y=2021&dfrom_m=04&dfrom_d=01&dto_y=2023&dto_m=09&dto_d=11&noct=1" 31 32# URLを開く 33browser.get(url) 34 35# 各種情報を格納するリストを準備 36page_urls: list[str] = [] 37posted_dates: list[str] = [] 38texts: list[str] = [] 39 40# 質問の総数を取得して表示 41total_questions = browser.find_element( 42 By.XPATH, "/html/body/div/div/div/div/div[2]/div[1]/div[6]/p" 43) 44all_split = total_questions.text.split("件") 45print(all_split[0]) 46 47# 質問の一覧ページを巡回して、URL と 質問日時を収集する 48while True: 49 headings = browser.find_elements( 50 By.CLASS_NAME, "h3.ListSearchResults_listSearchResults__heading__1T_RX" 51 ) 52 for heading in headings: 53 page_urls.append(heading.get_attribute("href")) 54 55 dates = browser.find_elements( 56 By.CSS_SELECTOR, 57 "h3.ListSearchResults_listSearchResults__informationDate__10t00", 58 ) 59 for date in dates: 60 posted_dates.append(date.text) 61 62 try: 63 next_button = browser.find_element(By.PARTIAL_LINK_TEXT, "次へ") 64 next_button.click() 65 time.sleep(3) 66 except Exception: 67 # 次へボタンが見つからない場合、プログラムを終了する 68 print("次へボタンが見つかりませんでした。スクレイピングを終了します。") 69 browser.quit() 70 break 71 72 73def get_question_text(url: str) -> None: 74 "質問ページにアクセスして本文を取得する" 75 76 browser.get(url) 77 78 try: 79 question_body = browser.find_element( 80 By.CSS_SELECTOR, 81 "div.ClapLv2QuestionItem_Chie-QuestionItem__Text__1AI-5", 82 ) 83 texts.append(question_body.text) 84 time.sleep(3) 85 86 except Exception as e: 87 print("質問の取得に失敗しました:", e) 88 print(f"失敗したURL: {url}") 89 texts.append("NA") 90 91 92# リストに格納した URL に順にアクセスして質問文を収集する 93for url in page_urls: 94 get_question_text(url) 95 96# 収集したデータを一つにまとめる 97data = zip(page_urls, posted_dates, texts) 98 99# データを CSV に書き出す 100with open("chiebukuro.csv", "w") as f: 101 writer = csv.writer(f) 102 for row in data: 103 writer.writerow(row) 104 105browser.quit()

投稿2023/09/14 05:21

編集2023/09/14 05:24
Demerara

総合スコア397

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問