前提・実現したいこと
データ収集で8万件のデータを集めています。
800件くらいまでは正常にできていたのですが、突然検索ができないエラーが出てきて何が何だかわかりません。
このコードでは下記の動きを実行しています。
0. エクセルファイルより検索キーワードを取得、 !! ここでエラー文が出ている? !!
0. seleniumでそのキーワードを検索、出てきたリンクを取得(配列に入れる)
0. requestsでそのリンクにアクセス、該当のキーワードをbeautiful soupで検索する
0. 結果をエクセルに入れる
という動きを想定しています。
発生している問題・エラーメッセージ
Traceback (most recent call last): File "/Users/USERNAME/Desktop/cloud_mail/py.py", line 144, in <module> link_search(keyword) File "/Users/USERNAME/Desktop/cloud_mail/py.py", line 38, in link_search search_bar.submit() File "/Users/USERNAME/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 84, in submit form = self.find_element(By.XPATH, "./ancestor-or-self::form") File "/Users/USERNAME/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 718, in find_element return self._execute(Command.FIND_CHILD_ELEMENT, File "/Users/USERNAME/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webelement.py", line 693, in _execute return self._parent.execute(command, params) File "/Users/USERNAME/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 418, in execute self.error_handler.check_response(response) File "/Users/USERNAME/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 243, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document (Session info: headless chrome=96.0.4664.55) Stacktrace: 0 chromedriver 0x0000000105b87bc9 __gxx_personality_v0 + 573977 1 chromedriver 0x0000000105b149a3 __gxx_personality_v0 + 102387 2 chromedriver 0x00000001056d6488 chromedriver + 173192 3 chromedriver 0x00000001056d9301 chromedriver + 185089 4 chromedriver 0x00000001056d9121 chromedriver + 184609 5 chromedriver 0x00000001056d93bc chromedriver + 185276 6 chromedriver 0x000000010570b66e chromedriver + 390766 7 chromedriver 0x00000001057008a7 chromedriver + 346279 8 chromedriver 0x0000000105728cfd chromedriver + 511229 9 chromedriver 0x00000001057007f5 chromedriver + 346101 10 chromedriver 0x0000000105728fce chromedriver + 511950 11 chromedriver 0x000000010573b961 chromedriver + 588129 12 chromedriver 0x0000000105728f73 chromedriver + 511859 13 chromedriver 0x00000001056ff0e0 chromedriver + 340192 14 chromedriver 0x0000000105700345 chromedriver + 344901 15 chromedriver 0x0000000105b44d5f __gxx_personality_v0 + 299951 16 chromedriver 0x0000000105b5b8db __gxx_personality_v0 + 393003 17 chromedriver 0x0000000105b6185f __gxx_personality_v0 + 417455 18 chromedriver 0x0000000105b5d00a __gxx_personality_v0 + 398938 19 chromedriver 0x0000000105b3995c __gxx_personality_v0 + 253868 20 chromedriver 0x0000000105b78198 __gxx_personality_v0 + 509928 21 chromedriver 0x0000000105b78321 __gxx_personality_v0 + 510321 22 chromedriver 0x0000000105b8f108 __gxx_personality_v0 + 603992 23 libsystem_pthread.dylib 0x00007fff205fb950 _pthread_start + 224 24 libsystem_pthread.dylib 0x00007fff205f747b thread_start + 15
該当のソースコード
python
1from selenium import webdriver 2from selenium.webdriver.common.keys import Keys 3from selenium.webdriver.common.by import By 4import chromedriver_binary 5from selenium.webdriver.common.action_chains import ActionChains 6from selenium.webdriver.chrome.options import Options 7from time import sleep, time 8import random 9import requests 10from bs4 import BeautifulSoup 11import re 12from fake_useragent import UserAgent 13import openpyxl 14import time 15 16# 全てのリンクを辿って取得 17 18# そのリンクのページでbs4で取得 19 20def get_keyword(ws, keyword_lists, ex_row): 21 while not ws.cell(ex_row, 2).value is None: 22 print(ws.cell(ex_row, 2).value) 23 keyword = ws.cell(ex_row, 2).value 24 keyword_lists.append(keyword) 25 ex_row = ex_row + 1 26 27 if ex_row > 10000: 28 break 29 30 if keyword == 'None': 31 break 32 33def link_search(keyword): 34 driver.get('https://www.google.co.jp') 35 36 search_bar = driver.find_element(By.NAME, "q") 37 search_bar.send_keys(keyword) 38 search_bar.submit() 39 # pythonと検索 40 sleep(8) 41 try: 42 # 検索結果で出てきたリンクを配列に入れる 43 for elem_h3 in driver.find_elements_by_xpath('//a/h3'): 44 i =+ 1 45 elem_a = elem_h3.find_element_by_xpath('..') 46 link_lists.append(elem_a.get_attribute('href')) 47 48 if i > 6: 49 break 50 except: 51 print('なし') 52 53 54def access(link_lists, keyword): 55 mail = '' 56 57 # 取得したリンクにアクセスして該当キーワードがあるか 58 for link in link_lists: 59 if link in 'google.co.jp': 60 break 61 62 try: 63 # スクレイピング対象の URL にリクエストを送り HTML を取得する 64 res = requests.get(link,headers=header,timeout=(6.0, 10.5),verify=False) 65 except (requests.exceptions.ConnectTimeout,requests.exceptions.ReadTimeout): 66 print('タイムアウトしました' + str(sleeptime) + '後に再開') 67 sleep(sleeptime) 68 break 69 except: 70 break 71 # レスポンスの HTML から BeautifulSoup オブジェクトを作る 72 try: 73 soup = BeautifulSoup(res.text, 'html.parser') 74 except: 75 print('アクセスできない') 76 print(link) 77 78 # 完全一致したら処理終了 79 if soup.find(text=keyword): 80 hantei_num = hantei[2] 81 mail = soup.find(text=keyword) 82 print('-------完全一致--------') 83 print(mail) 84 return hantei_num, mail, link 85 86 # 似たようなものがあれば 87 if soup.find(text=re.compile(keyword)): 88 hantei_num = hantei[1] 89 mail = soup.find(text=re.compile(keyword)) 90 print('-------似ている--------') 91 print(mail) 92 return hantei_num, mail, link 93 94 sleep(sleeptime) 95 # 何もないので 96 hantei_num = hantei[0] 97 link = '' 98 return hantei_num, mail, link, 99 100 101def ex(ex_arry, ex_row): 102 # Excelに登録 103 ex_col = 3 104 for ex_item in ex_arry: 105 cell = ws.cell( row=ex_row, column=ex_col ) 106 cell.value = ex_item 107 print(ex_col) 108 print(ex_row) 109 ex_col = ex_col + 1 110 wb.save(ex_name) 111 wb.close() 112 113 114if __name__ == '__main__': 115 # アクセスの定義づけ 116 options = Options() 117 options.add_argument('--headless') 118 driver = webdriver.Chrome(options=options) 119 ua = UserAgent() 120 header = {'user-agent':ua.chrome} 121 122 start_time = time.time() 123 124 ex_name = "email.xlsx" 125 wb = openpyxl.load_workbook( ex_name ) 126 ws = wb[ "作業リスト" ] 127 ex_row = 875 # 開始シート行 128 129 # 5〜10のランダム数字一時停止にしよう 130 sleeptime = random.randint(5,10) 131 132 # メールアドレスリスト 133 keyword_lists = [] 134 # 判定 135 hantei = ['×', '異なる', '同一'] 136 137 get_keyword(ws, keyword_lists, ex_row) 138 139 for keyword in keyword_lists: 140 # Googleの検索リンク初期化 141 link_lists = [] 142 143 # 該当するリンクを取得 144 link_search(keyword) 145 sleep(sleeptime) 146 print(keyword) 147 print('キーワード検索') 148 149 # メールアドレスのあるリンクをチェック 150 # 戻り値アドレス、判定num、リンクを変数に入れる 151 link, mail_item, h_num = access(link_lists, keyword) 152 print('--------結果------') 153 print(mail_item) 154 print(h_num) 155 print(link) 156 print('------------------') 157 # エクセルに追加 158 159 ex_arry = [] 160 161 ex_arry.append(h_num) 162 ex_arry.append(mail_item) 163 ex_arry.append(link) 164 165 print('エクセル記述') 166 print(ex_arry) 167 ex(ex_arry, ex_row) 168 ex_row = ex_row + 1
試したこと
stale element reference: element is not attached to the page document submit
このエラーが要素がない?というループエラーで表示されているという記事を見ますが、submit()の文面にエラーが出ているので、ループしていないな、、と思い理解不能です。
補足情報(FW/ツールのバージョンなど)
mac
python 3.8.8
selenium
webdriver
beautiful soup
requests
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。