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

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

新規登録して質問してみよう
ただいま回答率
85.48%
SEO

SEO(Search Engine Optimization)は、検索エンジンでウェブページがランキング上位に上がるように工夫する様々なテクニックの事です。

Python

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

selenium

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

Q&A

解決済

2回答

2919閲覧

seleniumでの上位検索サイトのキーワードとタイトル、URLの取得ができない

shuntatani

総合スコア1

SEO

SEO(Search Engine Optimization)は、検索エンジンでウェブページがランキング上位に上がるように工夫する様々なテクニックの事です。

Python

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

selenium

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

0グッド

0クリップ

投稿2020/06/11 17:04

前提・実現したいこと

SEOにおける上位サイト20位のキーワードとタイトル、URLを取得したい

タイトルをクリックして、戻って、次のタイトルをクリックして、戻ってを繰り返そうとしたところでエラーが出ました。

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

wifi おすすめ Traceback (most recent call last): File "test2.py", line 55, in <module> i.click() File "/Users/kitayashun/.pyenv/versions/3.6.5/lib/python3.6/site-packages/selenium/webdriver/remote/webelement.py", line 80, in click self._execute(Command.CLICK_ELEMENT) File "/Users/kitayashun/.pyenv/versions/3.6.5/lib/python3.6/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute return self._parent.execute(command, params) File "/Users/kitayashun/.pyenv/versions/3.6.5/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute self.error_handler.check_response(response) File "/Users/kitayashun/.pyenv/versions/3.6.5/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, 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: chrome=83.0.4103.97)

該当のソースコード

python

1#必要なライブラリのインポート 2from selenium import webdriver 3from selenium.webdriver.common.by import By 4import gspread 5import json 6from oauth2client.service_account import ServiceAccountCredentials 7import pandas as pd 8import os 9import time 10from selenium.webdriver.common.by import By 11from selenium.webdriver.support.ui import WebDriverWait 12from selenium.webdriver.support import expected_conditions as EC 13 14 15''' 16#スプレッドシートの設定 17scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive'] 18credentials = ServiceAccountCredentials.from_json_keyfile_name('spred-api.json', scope) 19gc = gspread.authorize(credentials) 20SPREADSHEET_KEY = '1vTyCfkkwrKaoogdZmicT7_V6eKaI1t3ZgChaiRGakXE' 21worksheet = gc.open_by_key(SPREADSHEET_KEY).sheet1 22 23 24 25import_value = int(worksheet.acell('A1').value) 26export_value = import_value+100 27worksheet.update_cell(1,2, export_value) 28''' 29 30#キーワードの検索 31driver = webdriver.Chrome('/usr/local/bin/chromedriver') 32driver.implicitly_wait(30) 33 34kws = ['wifi おすすめ','wimax 比較','クラウドwifi メリット'] 35 36driver.implicitly_wait(30) 37WebDriverWait(driver, 15).until(EC.presence_of_all_elements_located) 38 39#1ページ目の情報を取得 40for kw in kws: 41 driver.get('https://www.google.com/') 42 search_box = driver.find_element_by_name('q') 43 search_box.send_keys(kw) 44 search_box.submit() 45 #キーワード取得 46 keywords = kw 47 print(keywords) 48 #タイトル取得 49 h = driver.find_elements_by_class_name('LC20lb') 50 for i in h: 51 i.click() 52 driver.back() 53 54 55 56 57 58 59 60 61''' 62#2ページ目の情報を取得 63for kw in kws: 64 driver.get('https://www.google.com/') 65 search_box = driver.find_element_by_name('q') 66 search_box.send_keys(kw) 67 search_box.submit() 68 next = driver.find_element_by_link_text('次へ') 69 next.click() 70 #キーワード取得 71 keywords = kw 72 print(keywords) 73 #タイトル取得 74 h = driver.find_elements_by_class_name('LC20lb') 75 for i in h: 76 print(i.text) 77''' 78

試したこと

driver.implicitly_wait(30)を入れてみた

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

3点ほどお伝えしたいことがあります。

なぜエラーが起こるのか

これをみてください。

class名取得はNG

何度か試せば分かりますが、googleは検索するたびにclass属性がランダム(?)に変化します。
よって今回class属性を元にDOMをみるのはナンセンスです。

スクレイピング許可

ググればすぐ出てくると思いますがgoogleはスクレイピングを禁止しています。
私は法律詳しくないですが、不正アクセスとみなされる可能性もあるかもしれません。


と踏まえた上で、一応コードを載せておきます。
とはいえ実際に動かして検証はしていないのでエラーが出た際はご愛嬌で。

python

1results = {} 2KWS = ['wifi おすすめ','wimax 比較','クラウドwifi メリット'] 3 4driver = webdriver.Chrome('/usr/local/bin/chromedriver') 5driver.get('https://www.google.com/') 6 7for kw in KWS: 8 9 results[kw] = [] 10 driver.execute_script('document.getElementsByName("q")[0].value="%s";' % kw) 11 driver.execute_script('document.getElementsByTagName("button")[0].click()') 12 is_second_page = False 13 14 while True: 15 for i in range(len(driver.find_elements_by_css_selector('#rso > div > div > div > a'))): 16 one_data = {} 17 a_tag = driver.find_elements_by_css_selector('#rso > div > div > div > a')[i] 18 a_tag.click() 19 one_data['title'] = driver.title 20 one_data['url'] = driver.current_url 21 driver.back() 22 results[kw].append(one_data) 23 24 if is_second_page: 25 driver.execute_script('document.getElementById("pnnext").click()') 26 is_second_page = True 27 else: 28 break 29 30print(results)

検索結果一覧ページの時点でhref属性にURLがくっついているので、
それらを一括で取得したあと、それぞれにdriver.getで遷移していけば、
わざわざ検索結果一覧にback必要はないのですが、
少々プログラムが複雑になりそうなのでやめておきました。

投稿2020/06/12 13:33

shirai

総合スコア1290

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

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

shuntatani

2020/06/13 07:27

ご丁寧に回答いただきありがとうございます!! 試してみます!
guest

0

今表示しているのではないページの要素を使おうとしたというエラーです。

i.click()ページ遷移したらその瞬間にhの要素は無効になります。
driver.back()で戻ったら、再度h = driver.find_elements_by_class_name('LC20lb')をやり直す必要があります。

#追記

Python

1 for i in range(len(driver.find_elements_by_class_name('LC20lb'))): 2 h = driver.find_elements_by_class_name('LC20lb') 3 h[i].click() 4 driver.back()

でしょうか。

投稿2020/06/11 22:40

編集2020/06/11 23:55
otn

総合スコア84538

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

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

shuntatani

2020/06/11 23:07

ご回答ありがとうございます。 ご指摘の通り試してみたのですが、同じエラーが出てしまいました。 何か他に方法はありませんでしょうか?教えていただけると幸いです。
otn

2020/06/11 23:47

多分、修正の仕方が悪いのだと思います。
shuntatani

2020/06/12 01:35

送ってもらったコードをコピペして貼り付けたところIndexError: list index out of rangeが発生しました。自分なりに調べて、数字を変えたりしてみたのですが、どうにも修正できません。この場合はどうしたら良いのでしょうか?
otn

2020/06/12 01:54

うーむ。実行する毎に、driver.find_elements_by_class_name('LC20lb') の個数が違うと言うことですよね。 もっとページ構成を調べる必要があるかと思います。 毎回違うなら、「何個目の要素まで処理したか」じゃなくて「どの要素を処理したか」を記録して進めるようなことが必要でしょう、
shuntatani

2020/06/12 04:13

頑張ってみます!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問